library(tidyverse)
library(reshape2)
library(forcats)
library(randomForest)
library(lubridate)
library(vegan)
library(broom)
library(biobroom)
setwd("~/Google Drive/RMB/Analyses/LifeCycle/")
The working directory was changed to /Users/edwards/Google Drive/RMB/Analyses/LifeCycle inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the the working directory for notebook chunks.
lc_data <- readRDS("~/Google Drive/RMB/Analyses/LifeCycle/lc_long_data.rds")
tax <- readRDS("~/RMB/Reference/gg_otus_tax.rds")

Separate into testing and training data

Run the commented code below if you want to do that

training_samples <- lc_data %>% 
  filter(Site == "Arbuckle" | Site == "Jonesboro") %>% 
  filter(Season != "2015" & paste(Site, Season) != "Arbuckle 2016") %>% 
  group_by(SampleID, Compartment, Age, Site, Season) %>% 
  summarise(n()) %>% 
  group_by(Compartment, Age, Site, Season) %>% 
  sample_frac(0.5) %>% 
  mutate(type = "Train")
train_data <- lc_data %>% 
  inner_join(training_samples %>% ungroup() %>% select(SampleID, type), by = "SampleID") %>% 
  group_by(variable) %>% 
  filter(sum(value) > 0) %>% 
  mutate(RA = (value / Depth) * 1000, log2value = log2(RA + 1))
test_data <- lc_data %>% ungroup() %>% 
  filter(paste(Season, Site) != "2016 Arbuckle") %>% 
  anti_join(training_samples %>% ungroup() %>% select(SampleID, type), by = "SampleID") %>% 
  mutate(type = "Test") %>% 
  group_by(variable) %>%  
  mutate(RA = (value / Depth) * 1000, log2value = log2(RA + 1))
#lc_data <- NULL
train_data <- readRDS("~/Google Drive/RMB/Analyses/LifeCycle/Data/RF/train_data.rds")
test_data <- readRDS("~/Google Drive/RMB/Analyses/LifeCycle/Data/RF/test_data.rds")

Functions for doing Random Forests on Tidy Data

## When using this function for each compartment and each site start from the third column
## If using for combining both sites, start at the fourth column
rfcv_tidy <- function(x){
  cv <- rfcv(x[,4:ncol(x)], x$Age, cv.fold = 10, log = T)
  paste(names(cv$error), cv$error, sep = "_")
}
get_importance <- function(x){
  rf <- randomForest(x[,4:ncol(x)], x$Age, importance = T)
  imps <- as.data.frame(rf$importance)
  imps$variable <- row.names(imps)
  names(imps)[1] <- "PercIncMSE"
  as_tibble(imps)
}
tidy_randomforest <- function(x) {
  randomForest(x[,4:ncol(x)], x$Age, importance = F, keep.forest = T)
}
tidy_predict <- function(model, data) {
  predict(model, data[,4:ncol(data)])
}
cvs <- train_data %>% 
  select(type, Compartment, Site, Age, log2value, variable, SampleID) %>% 
  spread(variable, log2value, fill = 0) %>% 
  group_by(Compartment, Site, type) %>% 
  nest() %>% 
  filter(Compartment != "Bulk Soil" & type == "Train") %>% 
  mutate(cv = map(data, ~rfcv_tidy(.)))
cvs %>% 
  unnest(cv) %>% 
  separate(cv, c("OTUs", "Error"), "_", convert = T) %>% 
  ggplot(aes(OTUs, Error, color = Site)) +
  geom_line() +
  facet_grid(.~Compartment) +
  scale_x_log10()

cvs %>% 
  unnest(cv) %>% 
  separate(cv, c("OTUs", "Error"), "_", convert = T) %>% 
  group_by(Compartment, Site) %>% 
  filter(Error == min(Error))

Let’s idenitify the most important OTUs

imps <- train_data %>% 
  filter(Compartment != "Bulk Soil" & type == "Train" & Compartment != "Rhizoplane") %>% 
  select(SampleID, Age, Compartment, Site, variable, log2value) %>% 
  spread(variable, log2value, fill = 0) %>% 
  group_by(Site, Compartment) %>% 
  nest() %>% 
  mutate(imp = map(data, ~get_importance(.)))
Error: could not find function "get_importance"
rf_sparse <- train_data %>% 
  inner_join(top_otus, by = c("Compartment", "Site", "variable")) %>% 
  select(SampleID, Age, Compartment, type, variable, log2value, Site) %>% 
  group_by(Compartment, type, Site) %>%
  nest(., .key = "train_data") %>% 
  mutate(train_spread_data = map(train_data, ~spread(., variable, log2value, fill = 0))) %>% 
  mutate(rf = map(train_spread_data, ~tidy_randomforest(.)))
joining factor and character vector, coercing into character vector
rf_sparse %>% 
  mutate(predictions = map2(rf, train_spread_data, predict)) %>% 
  unnest(train_spread_data, predictions) %>% 
  select(Compartment, Site, predictions, Age) %>% 
  ggplot(aes(Age, predictions)) +
  geom_point() +
  facet_grid(Compartment ~ Site)

write_rds(rf_sparse, path = "~/Google Drive/RMB/Analyses/LifeCycle/Data/RF/rf_sparse.rds")
safe_predict <- possibly(predict, NA_real_)
arb_model_test_predictions <- bind_rows(train_data, test_data) %>% 
  inner_join(top_otus %>% ungroup() %>% filter(Site == "Arbuckle") %>% select(Compartment, variable), by = c("variable", "Compartment")) %>% 
  select(SampleID, Age, variable, log2value, Site, Compartment, Season, type, Date, Cultivar) %>% 
  group_by(Compartment, Season, type, Site, SampleID, Age, Date, Cultivar) %>% 
  mutate(log2value = ifelse(is.na(log2value), 0, log2value)) %>% 
  nest() %>% 
  mutate(spread_data = map(data, ~(spread(., variable, log2value, fill = 0)))) %>% 
  select(-data) %>% 
  inner_join(rf_sparse %>% filter(Site == "Arbuckle") %>% ungroup() %>% select(Compartment, rf), by = "Compartment") %>% 
  mutate(predictions = map2(rf, spread_data, safe_predict)) %>% 
  mutate(model = paste("Arbuckle", Compartment))
joining factor and character vector, coercing into character vector
ark_model_test_predictions <- bind_rows(train_data, test_data) %>% 
  inner_join(top_otus %>% ungroup() %>% filter(Site == "Jonesboro") %>% select(Compartment, variable), by = c("variable", "Compartment")) %>% 
  select(SampleID, Age, variable, log2value, Site, Compartment, Season, type, Date, Cultivar) %>% 
  group_by(Compartment, Season, type, Site, SampleID, Age, Date, Cultivar) %>% 
  mutate(log2value = ifelse(is.na(log2value), 0, log2value)) %>% 
  nest() %>% 
  mutate(spread_data = map(data, ~(spread(., variable, log2value, fill = 0)))) %>% 
  select(-data) %>% 
  inner_join(rf_sparse %>% filter(Site == "Jonesboro") %>% ungroup() %>% select(Compartment, rf), by = "Compartment") %>% 
  mutate(predictions = map2(rf, spread_data, safe_predict)) %>% 
  mutate(model = paste("Jonesboro", Compartment))
joining factor and character vector, coercing into character vector

Make a common model

top_otus_combo <- rf_sparse_combo %>% 
  mutate(importance = map(rf, ~get_importance(.))) %>% 
  unnest(importance)
Error: could not find function "importance"

safe_lm <- possibly(lm, NA_real_)
site_lm <- bind_rows(train_data, test_data) %>%
  filter(Compartment == "Endosphere" | Compartment == "Rhizosphere")
  inner_join(same_ages, by = "Age") %>% 
  ungroup() %>% select(Age, SampleID, Compartment, Site, log2value, Season, variable) %>% 
  filter(Site == "Arbuckle" | Site == "Jonesboro") %>% 
  filter(Season != 2015) %>% 
  group_by(variable, Compartment) %>% 
  filter(sum(log2value > 0) / n() > 0.1) %>% 
  group_by(Compartment, variable, Age) %>% 
  nest() %>% 
  mutate(model = map(data, ~tidy(safe_lm(log2value ~ Site, .)))) %>% 
  unnest(model)
  
saveRDS(site_lm, "~/Google Drive/RMB/Analyses/LifeCycle/Data/site_lm.rds")

lm_classification <- site_lm %>% 
  filter(p.value != "NaN" & term == "SiteJonesboro") %>% 
  group_by(Compartment) %>% 
  filter(Compartment != "Bulk Soil") %>% 
  mutate(p.adj = p.adjust(p.value, "bon")) %>% 
  filter(p.adj <= 0.05) %>% 
  mutate(Site = ifelse(estimate < 0, "Arbuckle", "Jonesboro")) 

lm_classification %>% 
  group_by(Compartment, Site, Age) %>% 
  summarise(n = n())  %>% ungroup() %>% 
  mutate(Compartment = fct_relevel(Compartment, "Rhizosphere", "Endosphere")) %>% 
  ggplot(aes(Age, n, fill = Site)) +
  geom_bar(stat = "identity", position = "dodge") +
  facet_grid(.~Compartment) +
  scale_fill_manual(values = c("#f57670ff", "steelblue")) +
  theme_minimal()

lm_classification %>% 
  group_by(Compartment, variable) %>% 
  summarise(n = n()) %>% 
  group_by(Compartment) %>% 
  summarise(n = n())

lm_classification_abund <- bind_rows(train_data, test_data) %>%
  inner_join(lm_classification, by = c("variable", "Compartment", "Site", "Age")) %>% 
  group_by(Compartment, Site, Age, SampleID) %>% 
  summarise(total = sum(RA))


lm_classification_abund %>% 
  group_by(Compartment, Site, Age) %>% 
  summarise(mean_ab = mean(total / 10), se = sd(total / 10) / sqrt(n())) %>% ungroup() %>% 
  mutate(Compartment = fct_relevel(Compartment, "Rhizosphere", "Endosphere")) %>% 
  ggplot(aes(Age, mean_ab, fill = Site)) +
  geom_bar(stat = "identity", position = "dodge") +
  geom_errorbar(aes(ymin = mean_ab - se, ymax = mean_ab + se), position = position_dodge(width = 12.5), width = 0.1, size = 0.2) +
  facet_grid(.~Compartment) +
  scale_fill_manual(values = c("#f57670ff", "steelblue")) +
  theme_minimal()
  
  
  
lm_classification_abund %>% 
  group_by(Compartment, Site) %>% 
  nest() %>% 
  mutate(model = map(data, ~tidy(lm(total ~ Age, .)))) %>% 
  unnest(model) %>% 
  filter(term != "(Intercept)") %>% 
  mutate(p.adj = p.adjust(p.value, "bon"))
  

lm_classification %>% 
  group_by(Compartment, Site, variable) %>% 
  summarise(count = n()) %>% 
  group_by(count, Site, Compartment) %>% 
  summarise(count2 = n()) %>% 
  ggplot(aes(count, count2)) +
  geom_bar(stat = "identity") +
  facet_grid(Compartment ~ Site)

Are early colonizing OTUs differentially abundant from the soil

peak_per_age_rs %>%
  select(variable, peak = Age) %>%
  inner_join(spline_predictions_rs, by = "variable") %>%
  inner_join(tax, by = "variable") %>% 
  mutate(group_var = paste(variable, Family)) %>% 
  group_by(variable) %>% 
  mutate(scaled_percent = (percent - min(percent)) / (max(percent) - min(percent)),
         scaled_fit = (.fitted - min(.fitted)) / (max(.fitted) - min(.fitted))) %>% 
  ungroup() %>% 
  mutate(variable = reorder(variable, peak)) %>% 
  arrange(variable) %>% 
  mutate(variable.f = reorder(as.character(variable), desc(variable))) %>% 
  group_by(variable.f) %>%
  nest(-variable.f) %>% 
  mutate(order = (0:(nrow(.)-1))*0.5) %>% 
  mutate(order2 = 1:nrow(.)) %>% 
  unnest() %>% 
  inner_join(otu_directions_combo %>% ungroup() %>% select(Compartment, classification, variable), by = c("variable", "Compartment")) %>% 
  group_by(variable, Compartment, order2, Kingdom, Phylum, Class, Order, Genus, Species, classification) %>% 
  summarise(n = n())  %>% write_tsv("~/Google Drive/RMB/Analyses/LifeCycle/TABLES/ad_rs_plot_order.tsv")
Column `variable` joining factor and character vector, coercing into character vector

model_test_predictions_drought %>% 
  unnest(predictions) %>% 
  group_by(Compartment, Soil) %>%
  nest() %>% 
  mutate(an = map(data, ~aov(predictions ~ Treatment * Cultivar, .))) %>% 
  mutate(thst = map(an, ~tidy(TukeyHSD(.)))) %>% 
  unnest(thst) %>% 
  filter(adj.p.value <= 0.05)

LS0tCnRpdGxlOiAiUmFuZG9tIEZvcmVzdHMgMiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJlc2hhcGUyKQpsaWJyYXJ5KGZvcmNhdHMpCmxpYnJhcnkocmFuZG9tRm9yZXN0KQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeSh2ZWdhbikKbGlicmFyeShicm9vbSkKbGlicmFyeShiaW9icm9vbSkKCnNldHdkKCJ+L0dvb2dsZSBEcml2ZS9STUIvQW5hbHlzZXMvTGlmZUN5Y2xlLyIpCmBgYAoKYGBge3J9CnRheCA8LSByZWFkUkRTKCJ+L1JNQi9SZWZlcmVuY2UvZ2dfb3R1c190YXgucmRzIikKYGBgCgojIyBTZXBhcmF0ZSBpbnRvIHRlc3RpbmcgYW5kIHRyYWluaW5nIGRhdGEKClJ1biB0aGUgY29tbWVudGVkIGNvZGUgYmVsb3cgaWYgeW91IHdhbnQgdG8gZG8gdGhhdApgYGB7cn0KI2xjX2RhdGEgPC0gcmVhZFJEUygifi9Hb29nbGUgRHJpdmUvUk1CL0FuYWx5c2VzL0xpZmVDeWNsZS9sY19sb25nX2RhdGEucmRzIikKCiN0cmFpbmluZ19zYW1wbGVzIDwtIGxjX2RhdGEgJT4lIAojICBmaWx0ZXIoU2l0ZSA9PSAiQXJidWNrbGUiIHwgU2l0ZSA9PSAiSm9uZXNib3JvIikgJT4lIAojICBmaWx0ZXIoU2Vhc29uICE9ICIyMDE1IiAmIHBhc3RlKFNpdGUsIFNlYXNvbikgIT0gIkFyYnVja2xlIDIwMTYiKSAlPiUgCiMgIGdyb3VwX2J5KFNhbXBsZUlELCBDb21wYXJ0bWVudCwgQWdlLCBTaXRlLCBTZWFzb24pICU+JSAKIyAgc3VtbWFyaXNlKG4oKSkgJT4lIAojICBncm91cF9ieShDb21wYXJ0bWVudCwgQWdlLCBTaXRlLCBTZWFzb24pICU+JSAKIyAgc2FtcGxlX2ZyYWMoMC41KSAlPiUgCiMgIG11dGF0ZSh0eXBlID0gIlRyYWluIikKCiN0cmFpbl9kYXRhIDwtIGxjX2RhdGEgJT4lIAojICBpbm5lcl9qb2luKHRyYWluaW5nX3NhbXBsZXMgJT4lIHVuZ3JvdXAoKSAlPiUgc2VsZWN0KFNhbXBsZUlELCB0eXBlKSwgYnkgPSAiU2FtcGxlSUQiKSAlPiUgCiMgIGdyb3VwX2J5KHZhcmlhYmxlKSAlPiUgCiMgIGZpbHRlcihzdW0odmFsdWUpID4gMCkgJT4lIAojICBtdXRhdGUoUkEgPSAodmFsdWUgLyBEZXB0aCkgKiAxMDAwLCBsb2cydmFsdWUgPSBsb2cyKFJBICsgMSkpCgojdGVzdF9kYXRhIDwtIGxjX2RhdGEgJT4lIHVuZ3JvdXAoKSAlPiUgCiMgIGZpbHRlcihwYXN0ZShTZWFzb24sIFNpdGUpICE9ICIyMDE2IEFyYnVja2xlIikgJT4lIAojICBhbnRpX2pvaW4odHJhaW5pbmdfc2FtcGxlcyAlPiUgdW5ncm91cCgpICU+JSBzZWxlY3QoU2FtcGxlSUQsIHR5cGUpLCBieSA9ICJTYW1wbGVJRCIpICU+JSAKIyAgbXV0YXRlKHR5cGUgPSAiVGVzdCIpICU+JSAKIyAgZ3JvdXBfYnkodmFyaWFibGUpICU+JSAgCiMgIG11dGF0ZShSQSA9ICh2YWx1ZSAvIERlcHRoKSAqIDEwMDAsIGxvZzJ2YWx1ZSA9IGxvZzIoUkEgKyAxKSkKCiN3cml0ZV9yZHModHJhaW5fZGF0YSwgIn4vR29vZ2xlIERyaXZlL1JNQi9BbmFseXNlcy9MaWZlQ3ljbGUvRGF0YS9SRi90cmFpbl9kYXRhLnJkcyIpCiN3cml0ZV9yZHModGVzdF9kYXRhLCAifi9Hb29nbGUgRHJpdmUvUk1CL0FuYWx5c2VzL0xpZmVDeWNsZS9EYXRhL1JGL3Rlc3RfZGF0YS5yZHMiKQpgYGAKCmBgYHtyfQp0cmFpbl9kYXRhIDwtIHJlYWRSRFMoIn4vR29vZ2xlIERyaXZlL1JNQi9BbmFseXNlcy9MaWZlQ3ljbGUvRGF0YS9SRi90cmFpbl9kYXRhLnJkcyIpCnRlc3RfZGF0YSA8LSByZWFkUkRTKCJ+L0dvb2dsZSBEcml2ZS9STUIvQW5hbHlzZXMvTGlmZUN5Y2xlL0RhdGEvUkYvdGVzdF9kYXRhLnJkcyIpCmBgYAoKCiMjIyBGdW5jdGlvbnMgZm9yIGRvaW5nIFJhbmRvbSBGb3Jlc3RzIG9uIFRpZHkgRGF0YQpgYGB7cn0KIyMgV2hlbiB1c2luZyB0aGlzIGZ1bmN0aW9uIGZvciBlYWNoIGNvbXBhcnRtZW50IGFuZCBlYWNoIHNpdGUgc3RhcnQgZnJvbSB0aGUgdGhpcmQgY29sdW1uCiMjIElmIHVzaW5nIGZvciBjb21iaW5pbmcgYm90aCBzaXRlcywgc3RhcnQgYXQgdGhlIGZvdXJ0aCBjb2x1bW4KcmZjdl90aWR5X2FnZSA8LSBmdW5jdGlvbih4KXsKICBjdiA8LSByZmN2KHhbLDQ6bmNvbCh4KV0sIHgkQWdlLCBjdi5mb2xkID0gMTAsIGxvZyA9IFQpCiAgcGFzdGUobmFtZXMoY3YkZXJyb3IpLCBjdiRlcnJvciwgc2VwID0gIl8iKQp9CgpnZXRfaW1wb3J0YW5jZV9hZ2UgPC0gZnVuY3Rpb24oeCl7CiAgcmYgPC0gcmFuZG9tRm9yZXN0KHhbLDQ6bmNvbCh4KV0sIHgkQWdlLCBpbXBvcnRhbmNlID0gVCkKICBpbXBzIDwtIGFzLmRhdGEuZnJhbWUocmYkaW1wb3J0YW5jZSkKICBpbXBzJHZhcmlhYmxlIDwtIHJvdy5uYW1lcyhpbXBzKQogIG5hbWVzKGltcHMpWzFdIDwtICJQZXJjSW5jTVNFIgogIGFzX3RpYmJsZShpbXBzKQp9Cgp0aWR5X3JhbmRvbWZvcmVzdF9hZ2UgPC0gZnVuY3Rpb24oeCkgewogIHJhbmRvbUZvcmVzdCh4Wyw0Om5jb2woeCldLCB4JEFnZSwgaW1wb3J0YW5jZSA9IEYsIGtlZXAuZm9yZXN0ID0gVCkKfQoKdGlkeV9wcmVkaWN0X2FnZSA8LSBmdW5jdGlvbihtb2RlbCwgZGF0YSkgewogIHByZWRpY3QobW9kZWwsIGRhdGFbLDQ6bmNvbChkYXRhKV0pCn0KYGBgCgpgYGB7cn0KY3ZzIDwtIHRyYWluX2RhdGEgJT4lIAogIHNlbGVjdCh0eXBlLCBDb21wYXJ0bWVudCwgU2l0ZSwgQWdlLCBsb2cydmFsdWUsIHZhcmlhYmxlLCBTYW1wbGVJRCkgJT4lIAogIHNwcmVhZCh2YXJpYWJsZSwgbG9nMnZhbHVlLCBmaWxsID0gMCkgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCBTaXRlLCB0eXBlKSAlPiUgCiAgbmVzdCgpICU+JSAKICBmaWx0ZXIoQ29tcGFydG1lbnQgIT0gIkJ1bGsgU29pbCIgJiB0eXBlID09ICJUcmFpbiIpICU+JSAKICBtdXRhdGUoY3YgPSBtYXAoZGF0YSwgfnJmY3ZfdGlkeV9hZ2UoLikpKQoKY3ZzICU+JSAKICB1bm5lc3QoY3YpICU+JSAKICBzZXBhcmF0ZShjdiwgYygiT1RVcyIsICJFcnJvciIpLCAiXyIsIGNvbnZlcnQgPSBUKSAlPiUgCiAgZ2dwbG90KGFlcyhPVFVzLCBFcnJvciwgY29sb3IgPSBTaXRlKSkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKC5+Q29tcGFydG1lbnQpICsKICBzY2FsZV94X2xvZzEwKCkKCmN2cyAlPiUgCiAgdW5uZXN0KGN2KSAlPiUgCiAgc2VwYXJhdGUoY3YsIGMoIk9UVXMiLCAiRXJyb3IiKSwgIl8iLCBjb252ZXJ0ID0gVCkgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCBTaXRlKSAlPiUgCiAgZmlsdGVyKEVycm9yID09IG1pbihFcnJvcikpCmBgYAoKIyMjIExldCdzIGlkZW5pdGlmeSB0aGUgbW9zdCBpbXBvcnRhbnQgT1RVcwpgYGB7cn0KaW1wcyA8LSB0cmFpbl9kYXRhICU+JSAKICBmaWx0ZXIoQ29tcGFydG1lbnQgIT0gIkJ1bGsgU29pbCIgJiB0eXBlID09ICJUcmFpbiIgJiBDb21wYXJ0bWVudCAhPSAiUmhpem9wbGFuZSIpICU+JSAKICBzZWxlY3QoU2FtcGxlSUQsIEFnZSwgQ29tcGFydG1lbnQsIFNpdGUsIHZhcmlhYmxlLCBsb2cydmFsdWUpICU+JSAKICBzcHJlYWQodmFyaWFibGUsIGxvZzJ2YWx1ZSwgZmlsbCA9IDApICU+JSAKICBncm91cF9ieShTaXRlLCBDb21wYXJ0bWVudCkgJT4lIAogIG5lc3QoKSAlPiUgCiAgbXV0YXRlKGltcCA9IG1hcChkYXRhLCB+Z2V0X2ltcG9ydGFuY2VfYWdlKC4pKSkKCnRvcF9vdHVzIDwtIGltcHMgJT4lIAogIHVubmVzdChpbXApICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCwgU2l0ZSkgJT4lIAogIHRvcF9uKDg1LCBQZXJjSW5jTVNFKQpgYGAKCgpgYGB7cn0Kc2l0ZV9zaGFyaW5nX3JmX290dXMgPC0gdG9wX290dXMgJT4lIAogIGdyb3VwX2J5KHZhcmlhYmxlLCBDb21wYXJ0bWVudCkgJT4lIAogIHN1bW1hcmlzZShuID0gbigpKSAlPiUgCiAgZmlsdGVyKG4gPT0gMikgJT4lIAogIGlubmVyX2pvaW4odGF4LCBieSA9ICJ2YXJpYWJsZSIpCgpjb21wYXJ0bWVudF9zaGFyaW5nX3JmX290dXMgPC0gdG9wX290dXMgJT4lIAogIGdyb3VwX2J5KHZhcmlhYmxlLCBTaXRlKSAlPiUgCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JSAKICBmaWx0ZXIobiA9PSAyKSAlPiUgCiAgaW5uZXJfam9pbih0YXgsIGJ5ID0gInZhcmlhYmxlIikKYGBgCgpgYGB7cn0KcmZfc3BhcnNlIDwtIHRyYWluX2RhdGEgJT4lIAogIGlubmVyX2pvaW4odG9wX290dXMsIGJ5ID0gYygiQ29tcGFydG1lbnQiLCAiU2l0ZSIsICJ2YXJpYWJsZSIpKSAlPiUgCiAgc2VsZWN0KFNhbXBsZUlELCBBZ2UsIENvbXBhcnRtZW50LCB0eXBlLCB2YXJpYWJsZSwgbG9nMnZhbHVlLCBTaXRlKSAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIHR5cGUsIFNpdGUpICU+JQogIG5lc3QoLiwgLmtleSA9ICJ0cmFpbl9kYXRhIikgJT4lIAogIG11dGF0ZSh0cmFpbl9zcHJlYWRfZGF0YSA9IG1hcCh0cmFpbl9kYXRhLCB+c3ByZWFkKC4sIHZhcmlhYmxlLCBsb2cydmFsdWUsIGZpbGwgPSAwKSkpICU+JSAKICBtdXRhdGUocmYgPSBtYXAodHJhaW5fc3ByZWFkX2RhdGEsIH50aWR5X3JhbmRvbWZvcmVzdF9hZ2UoLikpKQoKcmZfc3BhcnNlICU+JSAKICBtdXRhdGUocHJlZGljdGlvbnMgPSBtYXAyKHJmLCB0cmFpbl9zcHJlYWRfZGF0YSwgcHJlZGljdCkpICU+JSAKICB1bm5lc3QodHJhaW5fc3ByZWFkX2RhdGEsIHByZWRpY3Rpb25zKSAlPiUgCiAgc2VsZWN0KENvbXBhcnRtZW50LCBTaXRlLCBwcmVkaWN0aW9ucywgQWdlKSAlPiUgCiAgZ2dwbG90KGFlcyhBZ2UsIHByZWRpY3Rpb25zKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZmFjZXRfZ3JpZChDb21wYXJ0bWVudCB+IFNpdGUpCgp3cml0ZV9yZHMocmZfc3BhcnNlLCBwYXRoID0gIn4vR29vZ2xlIERyaXZlL1JNQi9BbmFseXNlcy9MaWZlQ3ljbGUvRGF0YS9SRi9yZl9zcGFyc2UucmRzIikKYGBgCgpgYGB7cn0Kc2FmZV9wcmVkaWN0IDwtIHBvc3NpYmx5KHByZWRpY3QsIE5BX3JlYWxfKQoKYXJiX21vZGVsX3Rlc3RfcHJlZGljdGlvbnMgPC0gYmluZF9yb3dzKHRyYWluX2RhdGEsIHRlc3RfZGF0YSkgJT4lIAogIGlubmVyX2pvaW4odG9wX290dXMgJT4lIHVuZ3JvdXAoKSAlPiUgZmlsdGVyKFNpdGUgPT0gIkFyYnVja2xlIikgJT4lIHNlbGVjdChDb21wYXJ0bWVudCwgdmFyaWFibGUpLCBieSA9IGMoInZhcmlhYmxlIiwgIkNvbXBhcnRtZW50IikpICU+JSAKICBzZWxlY3QoU2FtcGxlSUQsIEFnZSwgdmFyaWFibGUsIGxvZzJ2YWx1ZSwgU2l0ZSwgQ29tcGFydG1lbnQsIFNlYXNvbiwgdHlwZSwgRGF0ZSwgQ3VsdGl2YXIpICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCwgU2Vhc29uLCB0eXBlLCBTaXRlLCBTYW1wbGVJRCwgQWdlLCBEYXRlLCBDdWx0aXZhcikgJT4lIAogIG11dGF0ZShsb2cydmFsdWUgPSBpZmVsc2UoaXMubmEobG9nMnZhbHVlKSwgMCwgbG9nMnZhbHVlKSkgJT4lIAogIG5lc3QoKSAlPiUgCiAgbXV0YXRlKHNwcmVhZF9kYXRhID0gbWFwKGRhdGEsIH4oc3ByZWFkKC4sIHZhcmlhYmxlLCBsb2cydmFsdWUsIGZpbGwgPSAwKSkpKSAlPiUgCiAgc2VsZWN0KC1kYXRhKSAlPiUgCiAgaW5uZXJfam9pbihyZl9zcGFyc2UgJT4lIGZpbHRlcihTaXRlID09ICJBcmJ1Y2tsZSIpICU+JSB1bmdyb3VwKCkgJT4lIHNlbGVjdChDb21wYXJ0bWVudCwgcmYpLCBieSA9ICJDb21wYXJ0bWVudCIpICU+JSAKICBtdXRhdGUocHJlZGljdGlvbnMgPSBtYXAyKHJmLCBzcHJlYWRfZGF0YSwgc2FmZV9wcmVkaWN0KSkgJT4lIAogIG11dGF0ZShtb2RlbCA9IHBhc3RlKCJBcmJ1Y2tsZSIsIENvbXBhcnRtZW50KSkKCmFya19tb2RlbF90ZXN0X3ByZWRpY3Rpb25zIDwtIGJpbmRfcm93cyh0cmFpbl9kYXRhLCB0ZXN0X2RhdGEpICU+JSAKICBpbm5lcl9qb2luKHRvcF9vdHVzICU+JSB1bmdyb3VwKCkgJT4lIGZpbHRlcihTaXRlID09ICJKb25lc2Jvcm8iKSAlPiUgc2VsZWN0KENvbXBhcnRtZW50LCB2YXJpYWJsZSksIGJ5ID0gYygidmFyaWFibGUiLCAiQ29tcGFydG1lbnQiKSkgJT4lIAogIHNlbGVjdChTYW1wbGVJRCwgQWdlLCB2YXJpYWJsZSwgbG9nMnZhbHVlLCBTaXRlLCBDb21wYXJ0bWVudCwgU2Vhc29uLCB0eXBlLCBEYXRlLCBDdWx0aXZhcikgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCBTZWFzb24sIHR5cGUsIFNpdGUsIFNhbXBsZUlELCBBZ2UsIERhdGUsIEN1bHRpdmFyKSAlPiUgCiAgbXV0YXRlKGxvZzJ2YWx1ZSA9IGlmZWxzZShpcy5uYShsb2cydmFsdWUpLCAwLCBsb2cydmFsdWUpKSAlPiUgCiAgbmVzdCgpICU+JSAKICBtdXRhdGUoc3ByZWFkX2RhdGEgPSBtYXAoZGF0YSwgfihzcHJlYWQoLiwgdmFyaWFibGUsIGxvZzJ2YWx1ZSwgZmlsbCA9IDApKSkpICU+JSAKICBzZWxlY3QoLWRhdGEpICU+JSAKICBpbm5lcl9qb2luKHJmX3NwYXJzZSAlPiUgZmlsdGVyKFNpdGUgPT0gIkpvbmVzYm9ybyIpICU+JSB1bmdyb3VwKCkgJT4lIHNlbGVjdChDb21wYXJ0bWVudCwgcmYpLCBieSA9ICJDb21wYXJ0bWVudCIpICU+JSAKICBtdXRhdGUocHJlZGljdGlvbnMgPSBtYXAyKHJmLCBzcHJlYWRfZGF0YSwgc2FmZV9wcmVkaWN0KSkgJT4lIAogIG11dGF0ZShtb2RlbCA9IHBhc3RlKCJKb25lc2Jvcm8iLCBDb21wYXJ0bWVudCkpCmBgYAoKYGBge3J9CmJpbmRfcm93cyhhcmJfbW9kZWxfdGVzdF9wcmVkaWN0aW9ucywgYXJrX21vZGVsX3Rlc3RfcHJlZGljdGlvbnMpICAlPiUgCiAgZmlsdGVyKFNpdGUgPT0gIkFyYnVja2xlIiB8IFNpdGUgPT0gIkpvbmVzYm9ybyIpICU+JSAKICB1bm5lc3QocHJlZGljdGlvbnMpICU+JSAKICBtdXRhdGUoRGF0ZSA9IG1keShEYXRlKSkgJT4lIAogIG11dGF0ZShTZWFzb24yID0geWVhcihEYXRlKSkgJT4lIAogIG11dGF0ZShyZXNpZHVhbCA9IEFnZSAtIHByZWRpY3Rpb25zKSAlPiUgCiAgbXV0YXRlKGZpbGwgPSBmYWN0b3IocGFzdGUoU2l0ZSwgdHlwZSkpKSAlPiUgCiAgbXV0YXRlKGZpbGwgPSBmY3RfcmVsZXZlbChmaWxsLCAiQXJidWNrbGUgVHJhaW4iLCAiQXJidWNrbGUgVGVzdCIsICJKb25lc2Jvcm8gVHJhaW4iLCAiSm9uZXNib3JvIFRlc3QiKSkgJT4lIAogIG11dGF0ZShtb2RlbCA9IGZjdF9yZWxldmVsKG1vZGVsLCAiQXJidWNrbGUgUmhpem9zcGhlcmUiLCAiQXJidWNrbGUgRW5kb3NwaGVyZSIsICJKb25lc2Jvcm8gUmhpem9zcGhlcmUiLCAiSm9uZXNib3JvIEVuZG9zcGhlcmUiKSkgJT4lIAogIGdncGxvdChhZXMoZmFjdG9yKFNlYXNvbiksIGFicyhyZXNpZHVhbCksIGZpbGwgPSBmaWxsLCBhbHBoYSA9IHR5cGUpKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyID0gJ2JsYWNrJywgb3V0bGllci5zaXplID0gMC4yKSArCiAgZmFjZXRfZ3JpZCguIH4gbW9kZWwpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNmNTc2NzBmZiIsICIjZjU3NjcwZmYiLCAnc3RlZWxibHVlJywgJ3N0ZWVsYmx1ZScpKSArCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoMC41LCAwLjkpKSArCiAgbGFicyh4ID0gIlNlYXNvbiIsIHkgPSAiUHJlZGljdGlvbiBFcnJvciAoRGF5cykiKSArCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQpgYGAKCmBgYHtyfQpiaW5kX3Jvd3MoYXJiX21vZGVsX3Rlc3RfcHJlZGljdGlvbnMsIGFya19tb2RlbF90ZXN0X3ByZWRpY3Rpb25zKSAgJT4lIAogIGZpbHRlcihTaXRlID09ICJBcmJ1Y2tsZSIgfCBTaXRlID09ICJKb25lc2Jvcm8iKSAlPiUgCiAgdW5uZXN0KHByZWRpY3Rpb25zKSAlPiUgCiAgbXV0YXRlKERhdGUgPSBtZHkoRGF0ZSkpICU+JSAKICBtdXRhdGUoU2Vhc29uMiA9IHllYXIoRGF0ZSkpICU+JSAKICBtdXRhdGUocmVzaWR1YWwgPSBBZ2UgLSBwcmVkaWN0aW9ucykgJT4lIAogIG11dGF0ZShmaWxsID0gZmFjdG9yKHBhc3RlKFNpdGUsIHR5cGUpKSkgJT4lIAogIG11dGF0ZShmaWxsID0gZmN0X3JlbGV2ZWwoZmlsbCwgIkFyYnVja2xlIFRyYWluIiwgIkFyYnVja2xlIFRlc3QiLCAiSm9uZXNib3JvIFRyYWluIiwgIkpvbmVzYm9ybyBUZXN0IikpICU+JSAKICBtdXRhdGUobW9kZWwgPSBmY3RfcmVsZXZlbChtb2RlbCwgIkFyYnVja2xlIFJoaXpvc3BoZXJlIiwgIkFyYnVja2xlIEVuZG9zcGhlcmUiLCAiSm9uZXNib3JvIFJoaXpvc3BoZXJlIiwgIkpvbmVzYm9ybyBFbmRvc3BoZXJlIikpICU+JSAKICBnZ3Bsb3QoYWVzKEFnZSwgcHJlZGljdGlvbnMsIGZpbGwgPSBmaWxsLCBhbHBoYSA9IHR5cGUpKSArCiAgZ2VvbV9wb2ludCgpICsKICBmYWNldF9ncmlkKFNpdGUgfiBtb2RlbCkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI2Y1NzY3MGZmIiwgIiNmNTc2NzBmZiIsICdzdGVlbGJsdWUnLCAnc3RlZWxibHVlJykpICsKICBzY2FsZV9hbHBoYV9tYW51YWwodmFsdWVzID0gYygwLjUsIDAuOSkpICsKICBsYWJzKHggPSAiU2Vhc29uIiwgeSA9ICJQcmVkaWN0aW9uIEVycm9yIChEYXlzKSIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpCmBgYAoKCmBgYHtyfQpoZWF0X21hcF9vcmRlciA8LSBmdW5jdGlvbih4KSB7CgogIHgyIDwtIHggJT4lCiAgICB1bmdyb3VwKCkgJT4lIAogICAgc2VsZWN0KEFnZSwgdmFyaWFibGUsIG1lYW5fYWJ1bmQpICU+JSAKICAgIHNwcmVhZCh2YXJpYWJsZSwgbWVhbl9hYnVuZCkKICAKICBoYyA8LSBoY2x1c3QodmVnZGlzdCh0KHgyWywtMV0pLCBtZXRob2QgPSAiamFjY2FyZCIpKQogIAogIG9yZGVyIDwtIHRpYmJsZShwb3NpdGlvbiA9IGhjJG9yZGVyLCBvcmRlciA9IDE6bGVuZ3RoKGhjJG9yZGVyKSkgJT4lIAogICAgYXJyYW5nZShwb3NpdGlvbikgJT4lIAogICAgbXV0YXRlKHZhcmlhYmxlID0gbmFtZXMoeDIpWy0xXSkKICAKICB4ICU+JSAKICAgIGlubmVyX2pvaW4ob3JkZXIsIGJ5ID0gInZhcmlhYmxlIikKfQoKc2NhbGVkX290dXMgPC0gYmluZF9yb3dzKHRyYWluX2RhdGEsIHRlc3RfZGF0YSkgJT4lCiAgaW5uZXJfam9pbih0b3Bfb3R1cyAlPiUgdW5ncm91cCgpICU+JSBzZWxlY3QoQ29tcGFydG1lbnQsIHZhcmlhYmxlLCBTaXRlKSwgYnkgPSBjKCJTaXRlIiwgIkNvbXBhcnRtZW50IiwgInZhcmlhYmxlIikpICU+JSAKICBmaWx0ZXIoU2Vhc29uICE9IDIwMTUpICU+JSAKICBncm91cF9ieSh2YXJpYWJsZSwgU2l0ZSwgU2Vhc29uLCBDb21wYXJ0bWVudCkgJT4lIAogIG11dGF0ZShtaW5fdmFsdWUgPSBtaW4oUkEpLCBtYXhfdmFsdWUgPSBtYXgoUkEpLCBzY2FsZWRfdmFsdWUgPSAoUkEgLSBtaW5fdmFsdWUpIC8gKG1heF92YWx1ZSAtIG1pbl92YWx1ZSkpICU+JSAKICBncm91cF9ieShBZ2UsIENvbXBhcnRtZW50LCBTZWFzb24sIHZhcmlhYmxlLCBTaXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fYWJ1bmQgPSBtZWFuKHNjYWxlZF92YWx1ZSkpCgpwbG90dGluZ19vcmRlciA8LSBzY2FsZWRfb3R1cyAlPiUgCiAgZmlsdGVyKFNlYXNvbiAhPSAiMjAxNSIpICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCwgU2l0ZSwgU2Vhc29uKSAlPiUgCiAgbmVzdCgpICU+JSAKICBtdXRhdGUob3JkZXIgPSBtYXAoZGF0YSwgfmhlYXRfbWFwX29yZGVyKC4pKSkKCmFyYl9wbG90cyA8LSBwbG90dGluZ19vcmRlciAlPiUgCiAgZmlsdGVyKFNpdGUgPT0gIkFyYnVja2xlIikgJT4lIAogIHVubmVzdChvcmRlcikgJT4lIAogIG11dGF0ZShDb21wYXJ0bWVudCA9IGZjdF9yZWxldmVsKENvbXBhcnRtZW50LCAiUmhpem9zcGhlcmUiLCAiRW5kb3NwaGVyZSIpKSAlPiUgCiAgaW5uZXJfam9pbih0YXgsIGJ5ID0gInZhcmlhYmxlIikgJT4lIAogIGdncGxvdChhZXMoQWdlLCBvcmRlciwgZmlsbCA9IG1lYW5fYWJ1bmQpKSArCiAgZ2VvbV90aWxlKCkgKwogIGZhY2V0X2dyaWQoLn5Db21wYXJ0bWVudCkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG9ycyA9IGJyZXdlci5wYWwoOCwgIkduQnUiKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGxhYnMoeCA9ICIiLCB5ID0gIiIpCiAgCgphcmtfcGxvdHMgPC0gcGxvdHRpbmdfb3JkZXIgJT4lIAogIGZpbHRlcihTaXRlID09ICJKb25lc2Jvcm8iKSAlPiUgCiAgdW5uZXN0KG9yZGVyKSAlPiUgCiAgbXV0YXRlKENvbXBhcnRtZW50ID0gZmN0X3JlbGV2ZWwoQ29tcGFydG1lbnQsICJSaGl6b3NwaGVyZSIsICJFbmRvc3BoZXJlIikpICU+JSAKICBnZ3Bsb3QoYWVzKEFnZSwgb3JkZXIsIGZpbGwgPSBtZWFuX2FidW5kKSkgKwogIGdlb21fdGlsZSgpICsKICBmYWNldF9ncmlkKC5+Q29tcGFydG1lbnQpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvcnMgPSBicmV3ZXIucGFsKDgsICJHbkJ1IikpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBsYWJzKHggPSAiIiwgeSA9ICIiKQoKZ3JpZC5hcnJhbmdlKGFyYl9wbG90cywgYXJrX3Bsb3RzLCBucm93ID0gMSkKYGBgCgoKYGBge3J9Cm90dV9kaXJlY3Rpb25zIDwtIGJpbmRfcm93cyh0cmFpbl9kYXRhLCB0ZXN0X2RhdGEpICU+JQogIGlubmVyX2pvaW4odG9wX290dXMgJT4lIHVuZ3JvdXAoKSAlPiUgc2VsZWN0KENvbXBhcnRtZW50LCB2YXJpYWJsZSwgU2l0ZSksIGJ5ID0gYygiU2l0ZSIsICJDb21wYXJ0bWVudCIsICJ2YXJpYWJsZSIpKSAlPiUgCiAgZmlsdGVyKFNlYXNvbiAhPSAyMDE1KSAlPiUgCiAgZ3JvdXBfYnkodmFyaWFibGUsIFNpdGUsIFNlYXNvbiwgQ29tcGFydG1lbnQsIHZhcmlhYmxlKSAlPiUgCiAgbmVzdCgpICU+JSAKICBtdXRhdGUobW9kZWxzID0gbWFwKGRhdGEsIH50aWR5KGxtKGxvZzJ2YWx1ZSB+IEFnZSwgLikpKSkgJT4lIAogIHVubmVzdChtb2RlbHMpICU+JSAKICBmaWx0ZXIodGVybSAhPSAiKEludGVyY2VwdCkiKSAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIFNpdGUpICU+JSAKICBtdXRhdGUocC5hZGogPSBwLmFkanVzdChwLnZhbHVlLCAiQkgiKSkgJT4lIAogIG11dGF0ZShkaXJlY3Rpb24gPSBpZmVsc2UoZXN0aW1hdGUgPiAwLCAiaW5jcmVhc2luZyIsICJkZWNyZWFzaW5nIikpICU+JSAKICBtdXRhdGUoY2xhc3NpZmljYXRpb24gPSBpZmVsc2UocC5hZGogPiAwLjA1LCAibmV1dHJhbCIsIGRpcmVjdGlvbikpIAogIApvdHVfZGlyZWN0aW9ucyAlPiUgdW5ncm91cCgpICU+JSAKICBpbm5lcl9qb2luKHRheCwgYnkgPSAidmFyaWFibGUiKSAlPiUKICBtdXRhdGUoQ29tcGFydG1lbnQgPSBmY3RfcmVsZXZlbChDb21wYXJ0bWVudCwgIlJoaXpvc3BoZXJlIiwgIkVuZG9zcGhlcmUiKSkgJT4lIAogIG11dGF0ZShjbGFzc2lmaWNhdGlvbiA9IGZjdF9yZWxldmVsKGNsYXNzaWZpY2F0aW9uLCAiaW5jcmVhc2luZyIsICJuZXV0cmFsIiwgImRlY3JlYXNpbmciKSkgJT4lIAogIGdncGxvdChhZXMoUGh5bHVtMiwgZmlsbCA9IHBhc3RlKFBoeWx1bTIsIE9yZGVyKSkpICsKICBnZW9tX2JhcigpICsKICBmYWNldF9ncmlkKGNsYXNzaWZpY2F0aW9uICsgQ29tcGFydG1lbnQgfiBTaXRlKSArCiAgdGhlbWVfYncoKQoKb3R1X2RpcmVjdGlvbnMgJT4lIAogIGlubmVyX2pvaW4odGF4LCBieSA9ICJ2YXJpYWJsZSIpICU+JSAKICBtdXRhdGUodGF4X2xldmVsID0gcGFzdGUoUGh5bHVtMiwgT3JkZXIpKSAlPiUgCiAgZ3JvdXBfYnkoU2l0ZSwgdGF4X2xldmVsLCBjbGFzc2lmaWNhdGlvbikgJT4lIAogIHN1bW1hcmlzZShuID0gbigpKSAlPiUgCiAgbXV0YXRlKHNoYXJpbmcgPSBpZmVsc2UobiA+IDEsICJTaGFyZWQiLCAiVW5pcXVlIikpICU+JSAKICBncm91cF9ieShTaXRlLCBjbGFzc2lmaWNhdGlvbiwgc2hhcmluZykgJT4lIAogIHN1bW1hcmlzZShuID0gbigpKSAlPiUgCiAgZ2dwbG90KGFlcyhTaXRlLCBuLCBmaWxsID0gc2hhcmluZykpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIGZhY2V0X2dyaWQoLn5jbGFzc2lmaWNhdGlvbikKCnBsb3R0aW5nX29yZGVyICU+JSBmaWx0ZXIoU2l0ZSA9PSAiQXJidWNrbGUiKSAlPiUgdW5uZXN0KG9yZGVyKSAlPiUgCiAgaW5uZXJfam9pbihvdHVfZGlyZWN0aW9ucywgYnkgPSBjKCJ2YXJpYWJsZSIsICJDb21wYXJ0bWVudCIsICJTaXRlIikpICU+JSAKICBnZ3Bsb3QoYWVzKEFnZSwgb3JkZXIsIGZpbGwgPSBtZWFuX2FidW5kKSkgKwogIGdlb21fdGlsZSgpICsKICBmYWNldF9ncmlkKC5+Q29tcGFydG1lbnQpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvcnMgPSBicmV3ZXIucGFsKDgsICJHbkJ1IikpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gbWF4KEFnZSkgKyA3LCB5ID0gb3JkZXIsIGNvbG9yID0gY2xhc3NpZmljYXRpb24pKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZG9kZ2VyYmx1ZSIsICJnb2xkIiwgImdyZXk1MCIpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGxhYnMoeCA9ICIiLCB5ID0gIiIpCiAgCmBgYAoKCiMjIE1ha2UgYSBjb21tb24gbW9kZWwKYGBge3J9CmN2c19jb21ibyA8LSB0cmFpbl9kYXRhICU+JSAKICBzZWxlY3QodHlwZSwgQ29tcGFydG1lbnQsIFNpdGUsIEFnZSwgbG9nMnZhbHVlLCB2YXJpYWJsZSwgU2FtcGxlSUQpICU+JSAKICBzcHJlYWQodmFyaWFibGUsIGxvZzJ2YWx1ZSwgZmlsbCA9IDApICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCwgdHlwZSkgJT4lIAogIG5lc3QoKSAlPiUgCiAgZmlsdGVyKENvbXBhcnRtZW50ICE9ICJCdWxrIFNvaWwiICYgdHlwZSA9PSAiVHJhaW4iKSAlPiUgCiAgbXV0YXRlKGN2ID0gbWFwKGRhdGEsIH5yZmN2X3RpZHlfYWdlKC4pKSkKCmN2c19jb21ibyAlPiUgCiAgdW5uZXN0KGN2KSAlPiUgCiAgc2VwYXJhdGUoY3YsIGMoIk9UVXMiLCAiRXJyb3IiKSwgIl8iLCBjb252ZXJ0ID0gVCkgJT4lIAogIGdncGxvdChhZXMoT1RVcywgRXJyb3IpKSArCiAgZ2VvbV9saW5lKCkgKwogIGZhY2V0X2dyaWQoLn5Db21wYXJ0bWVudCkgKwogIHNjYWxlX3hfbG9nMTAoKQoKY3ZzX2NvbWJvICU+JSAKICB1bm5lc3QoY3YpICU+JSAKICBzZXBhcmF0ZShjdiwgYygiT1RVcyIsICJFcnJvciIpLCAiXyIsIGNvbnZlcnQgPSBUKSAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQpICU+JSAKICBmaWx0ZXIoRXJyb3IgPT0gbWluKEVycm9yKSkKYGBgCgoKYGBge3J9CmltcHNfY29tYm8gPC0gdHJhaW5fZGF0YSAlPiUgCiAgZmlsdGVyKENvbXBhcnRtZW50ICE9ICJCdWxrIFNvaWwiICYgdHlwZSA9PSAiVHJhaW4iICYgQ29tcGFydG1lbnQgIT0gIlJoaXpvcGxhbmUiKSAlPiUgCiAgc2VsZWN0KFNhbXBsZUlELCBBZ2UsIENvbXBhcnRtZW50LCBTaXRlLCB2YXJpYWJsZSwgbG9nMnZhbHVlKSAlPiUgCiAgc3ByZWFkKHZhcmlhYmxlLCBsb2cydmFsdWUsIGZpbGwgPSAwKSAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQpICU+JSAKICBuZXN0KCkgJT4lIAogIG11dGF0ZShpbXAgPSBtYXAoZGF0YSwgfmdldF9pbXBvcnRhbmNlX2FnZSguKSkpCgp0b3Bfb3R1c19jb21ibyA8LSBpbXBzX2NvbWJvICU+JSAKICB1bm5lc3QoaW1wKSAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQpICU+JSAKICB0b3Bfbig4NSwgUGVyY0luY01TRSkKCmNvbXBhcnRtZW50X3NoYXJpbmdfcmZfb3R1c19jb21ibyA8LSB0b3Bfb3R1c19jb21ibyAlPiUgCiAgZ3JvdXBfYnkodmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lIAogIGZpbHRlcihuID09IDIpICU+JSAKICBpbm5lcl9qb2luKHRheCwgYnkgPSAidmFyaWFibGUiKQpgYGAKYGBge3J9CnRvcF9vdHVzX2NvbWJvICU+JSAKICBpbm5lcl9qb2luKHRheCwgYnkgPSAidmFyaWFibGUiKSAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIHBhc3RlKFBoeWx1bSwgQ2xhc3MsIE9yZGVyLCBGYW1pbHkpKSAlPiUgCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCkgJT4lIAogIHN1bW1hcmlzZShuKCkpCmBgYAoKYGBge3J9CmdldF9pbXBvcnRhbmNlIDwtIGZ1bmN0aW9uKHJmKSB7CiAgYXNfdGliYmxlKHJvd25hbWVzX3RvX2NvbHVtbihkYXRhLmZyYW1lKGltcG9ydGFuY2UocmYpKSwgdmFyID0gInZhcmlhYmxlIikpCn0KCnJmX3NwYXJzZV9jb21ibyA8LSB0cmFpbl9kYXRhICU+JSAKICBpbm5lcl9qb2luKHRvcF9vdHVzX2NvbWJvLCBieSA9IGMoIkNvbXBhcnRtZW50IiwgInZhcmlhYmxlIikpICU+JSAKICBzZWxlY3QoU2FtcGxlSUQsIEFnZSwgQ29tcGFydG1lbnQsIHR5cGUsIHZhcmlhYmxlLCBsb2cydmFsdWUsIFNpdGUpICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCwgdHlwZSkgJT4lCiAgbmVzdCguLCAua2V5ID0gInRyYWluX2RhdGEiKSAlPiUgCiAgbXV0YXRlKHRyYWluX3NwcmVhZF9kYXRhID0gbWFwKHRyYWluX2RhdGEsIH5zcHJlYWQoLiwgdmFyaWFibGUsIGxvZzJ2YWx1ZSwgZmlsbCA9IDApKSkgJT4lIAogIG11dGF0ZShyZiA9IG1hcCh0cmFpbl9zcHJlYWRfZGF0YSwgfnRpZHlfcmFuZG9tZm9yZXN0KC4pKSkKCnJmX3NwYXJzZV9jb21ibyAlPiUgCiAgbXV0YXRlKHByZWRpY3Rpb25zID0gbWFwMihyZiwgdHJhaW5fc3ByZWFkX2RhdGEsIHByZWRpY3QpKSAlPiUgCiAgdW5uZXN0KHRyYWluX3NwcmVhZF9kYXRhLCBwcmVkaWN0aW9ucykgJT4lIAogIHNlbGVjdChDb21wYXJ0bWVudCwgU2l0ZSwgcHJlZGljdGlvbnMsIEFnZSkgJT4lIAogIGdncGxvdChhZXMoQWdlLCBwcmVkaWN0aW9ucykpICsKICBnZW9tX3BvaW50KCkgKwogIGZhY2V0X2dyaWQoQ29tcGFydG1lbnQgfiBTaXRlKQoKI3dyaXRlX3JkcyhyZl9zcGFyc2VfY29tYm8sIHBhdGggPSAifi9Hb29nbGUgRHJpdmUvUk1CL0FuYWx5c2VzL0xpZmVDeWNsZS9EYXRhL1JGL3JmX3NwYXJzZV9jb21iby5yZHMiKQpyZl9zcGFyc2VfY29tYm8gPC0gcmVhZFJEUygifi9Hb29nbGUgRHJpdmUvUk1CL0FuYWx5c2VzL0xpZmVDeWNsZS9EYXRhL1JGL3JmX3NwYXJzZV9jb21iby5yZHMiKQoKdG9wX290dXNfY29tYm8gPC0gcmZfc3BhcnNlX2NvbWJvICU+JSAKICBtdXRhdGUoaW1wb3J0YW5jZSA9IG1hcChyZiwgfmdldF9pbXBvcnRhbmNlKC4pKSkgJT4lIAogIHVubmVzdChpbXBvcnRhbmNlKQoKYGBgCgpgYGB7cn0Kc2FmZV9wcmVkaWN0IDwtIHBvc3NpYmx5KHByZWRpY3QsIE5BX3JlYWxfKQoKbW9kZWxfdGVzdF9wcmVkaWN0aW9uc19jb21ibyA8LSBiaW5kX3Jvd3ModHJhaW5fZGF0YSwgdGVzdF9kYXRhKSAlPiUgCiAgaW5uZXJfam9pbih0b3Bfb3R1c19jb21ibyAlPiUgdW5ncm91cCgpICU+JSBzZWxlY3QoQ29tcGFydG1lbnQsIHZhcmlhYmxlKSwgYnkgPSBjKCJ2YXJpYWJsZSIsICJDb21wYXJ0bWVudCIpKSAlPiUgCiAgc2VsZWN0KFNhbXBsZUlELCBBZ2UsIHZhcmlhYmxlLCBsb2cydmFsdWUsIFNpdGUsIENvbXBhcnRtZW50LCBTZWFzb24sIHR5cGUsIERhdGUsIEN1bHRpdmFyKSAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIFNlYXNvbiwgdHlwZSwgU2l0ZSwgU2FtcGxlSUQsIEFnZSwgRGF0ZSwgQ3VsdGl2YXIpICU+JSAKICBtdXRhdGUobG9nMnZhbHVlID0gaWZlbHNlKGlzLm5hKGxvZzJ2YWx1ZSksIDAsIGxvZzJ2YWx1ZSkpICU+JSAKICBuZXN0KCkgJT4lIAogIG11dGF0ZShzcHJlYWRfZGF0YSA9IG1hcChkYXRhLCB+KHNwcmVhZCguLCB2YXJpYWJsZSwgbG9nMnZhbHVlLCBmaWxsID0gMCkpKSkgJT4lIAogIHNlbGVjdCgtZGF0YSkgJT4lIAogIGlubmVyX2pvaW4ocmZfc3BhcnNlX2NvbWJvICU+JSB1bmdyb3VwKCkgJT4lIHNlbGVjdChDb21wYXJ0bWVudCwgcmYpLCBieSA9ICJDb21wYXJ0bWVudCIpICU+JSAKICBtdXRhdGUocHJlZGljdGlvbnMgPSBtYXAyKHJmLCBzcHJlYWRfZGF0YSwgc2FmZV9wcmVkaWN0KSkgJT4lIAogIG11dGF0ZShtb2RlbCA9IENvbXBhcnRtZW50KQoKbW9kZWxfdGVzdF9wcmVkaWN0aW9uc19jb21ibyAlPiUgCiAgdW5uZXN0KHByZWRpY3Rpb25zKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoU2FtcGxlSUQsIENvbXBhcnRtZW50LCBTaXRlLCB0eXBlLCBBZ2UsIEN1bHRpdmFyLCBwcmVkaWN0aW9ucywgbW9kZWwsIFNlYXNvbikgJT4lIAogIGZpbHRlcihTaXRlID09ICJBcmJ1Y2tsZSIgfCBTaXRlID09ICJKb25lc2Jvcm8iKSAlPiUgCiAgd3JpdGVfdHN2KC4sICJ+L0dvb2dsZSBEcml2ZS9STUIvQW5hbHlzZXMvTGlmZUN5Y2xlL1RBQkxFUy9hZ2VfcHJlZGljdGlvbnMudHh0IikKYGBgCgpgYGB7cn0KcHJlZF9wbG90IDwtIG1vZGVsX3Rlc3RfcHJlZGljdGlvbnNfY29tYm8gJT4lIAogIHVubmVzdChwcmVkaWN0aW9ucykgJT4lIAogIGZpbHRlcihTaXRlID09ICJBcmJ1Y2tsZSIgfCBTaXRlID09ICJKb25lc2Jvcm8iKSAlPiUgCiAgbXV0YXRlKENvbXBhcnRtZW50ID0gZmN0X3JlbGV2ZWwoQ29tcGFydG1lbnQsICJSaGl6b3NwaGVyZSIsICJFbmRvc3BoZXJlIikpICU+JSAKICBnZ3Bsb3QoYWVzKEFnZSwgcHJlZGljdGlvbnMsIGNvbG9yID0gZmFjdG9yKFNlYXNvbiksIHNoYXBlID0gdHlwZSkpICsKICBnZW9tX2FibGluZShzbG9wZSA9IDEsIGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRvdHRlZCIpICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE2LCAxKSkgKwogIGZhY2V0X2dyaWQoU2l0ZSB+IENvbXBhcnRtZW50KSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiNmNTc2NzBmZiIsICJyZWQiLCAic3RlZWxibHVlIikpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoeCA9ICJBZ2UgKERheXMpIiwgeSA9ICJQcmVkaWN0ZWQgQWdlIChEYXlzKSIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCm1vZGVsX3Rlc3RfcHJlZGljdGlvbnNfY29tYm8gJT4lIAogIHVubmVzdChwcmVkaWN0aW9ucykgJT4lIAogIGZpbHRlcihTaXRlICE9ICJBcmJ1Y2tsZSIgJiBTaXRlICE9ICJKb25lc2Jvcm8iKSAlPiUgCiAgbXV0YXRlKENvbXBhcnRtZW50ID0gZmN0X3JlbGV2ZWwoQ29tcGFydG1lbnQsICJSaGl6b3NwaGVyZSIsICJFbmRvc3BoZXJlIikpICU+JSAKICBnZ3Bsb3QoYWVzKFNpdGUsIHByZWRpY3Rpb25zLCBjb2xvciA9IFNpdGUpKSArCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAuMikpICsKICBmYWNldF9ncmlkKC5+Q29tcGFydG1lbnQpCmBgYCAKYGBge3J9Cm90dV9kaXJlY3Rpb25zX2NvbWJvIDwtIGJpbmRfcm93cyh0cmFpbl9kYXRhLCB0ZXN0X2RhdGEpICU+JQogIGlubmVyX2pvaW4odG9wX290dXNfY29tYm8gJT4lIHVuZ3JvdXAoKSAlPiUgc2VsZWN0KENvbXBhcnRtZW50LCB2YXJpYWJsZSksIGJ5ID0gYygiQ29tcGFydG1lbnQiLCAidmFyaWFibGUiKSkgJT4lIAogIGZpbHRlcihTZWFzb24gIT0gMjAxNSkgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCB2YXJpYWJsZSkgJT4lIAogIG5lc3QoKSAlPiUgCiAgbXV0YXRlKG1vZGVscyA9IG1hcChkYXRhLCB+dGlkeShsbShsb2cydmFsdWUgfiBBZ2UsIC4pKSkpICU+JSAKICB1bm5lc3QobW9kZWxzKSAlPiUgCiAgZmlsdGVyKHRlcm0gIT0gIihJbnRlcmNlcHQpIikgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50KSAlPiUgCiAgbXV0YXRlKHAuYWRqID0gcC5hZGp1c3QocC52YWx1ZSwgImJvbiIpKSAlPiUgCiAgbXV0YXRlKGRpcmVjdGlvbiA9IGlmZWxzZShlc3RpbWF0ZSA+IDAsICJJbmNyZWFzaW5nIiwgIkRlY3JlYXNpbmciKSkgJT4lIAogIG11dGF0ZShjbGFzc2lmaWNhdGlvbiA9IGlmZWxzZShwLmFkaiA+IDAuMDUsICJOZXV0cmFsIiwgZGlyZWN0aW9uKSkgCgojd3JpdGVfcmRzKG90dV9kaXJlY3Rpb25zX2NvbWJvLCBwYXRoID0gIn4vR29vZ2xlIERyaXZlL1JNQi9BbmFseXNlcy9MaWZlQ3ljbGUvRGF0YS9SRi9vdHVfZGlyZWN0aW9ucy5yZHMiKQpvdHVfZGlyZWN0aW9uc19jb21ibyA8LSByZWFkUkRTKCJ+L0dvb2dsZSBEcml2ZS9STUIvQW5hbHlzZXMvTGlmZUN5Y2xlL0RhdGEvUkYvb3R1X2RpcmVjdGlvbnMucmRzIikKCm90dV9kaXJlY3Rpb25zX2NvbWJvICU+JSAKICBpbm5lcl9qb2luKHRheCwgYnkgPSAidmFyaWFibGUiKSAlPiUKICBncm91cF9ieShQaHlsdW0yLCBDb21wYXJ0bWVudCwgY2xhc3NpZmljYXRpb24pICU+JSAKICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgZ3JvdXBfYnkoUGh5bHVtMikgJT4lIAogIG11dGF0ZSh0b3RhbCA9IHN1bShuKSkgJT4lIHVuZ3JvdXAoKSAlPiUgCiAgbXV0YXRlKFBoeWx1bTIgPSBmY3RfcmVvcmRlcihQaHlsdW0yLCB0b3RhbCkpICU+JSAKICBtdXRhdGUoY2xhc3NpZmljYXRpb24gPSBmY3RfcmVsZXZlbChjbGFzc2lmaWNhdGlvbiwgIk5ldXRyYWwiLCAiRGVjcmVhc2luZyIsICJJbmNyZWFzaW5nIikpICU+JSAKICBtdXRhdGUoQ29tcGFydG1lbnQgPSBmY3RfcmVsZXZlbChDb21wYXJ0bWVudCwgIlJoaXpvc3BoZXJlIiwgIkVuZG9zcGhlcmUiKSkgJT4lIAogIGdncGxvdChhZXMoUGh5bHVtMiwgbiwgZmlsbCA9IGNsYXNzaWZpY2F0aW9uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgZmFjZXRfZ3JpZCgufkNvbXBhcnRtZW50KSArCiAgY29vcmRfZmxpcCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJncmV5NTAiLCAiZG9kZ2VyYmx1ZSIsICJnb2xkIikpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKYGBgCmBgYHtyfQppbXBfYWJ1bmRfY29tYm8gPC0gYmluZF9yb3dzKHRyYWluX2RhdGEsIHRlc3RfZGF0YSkgJT4lCiAgaW5uZXJfam9pbihvdHVfZGlyZWN0aW9uc19jb21ibyAlPiUgdW5ncm91cCgpICU+JSBzZWxlY3QoQ29tcGFydG1lbnQsIHZhcmlhYmxlLCBjbGFzc2lmaWNhdGlvbiksIGJ5ID0gYygiQ29tcGFydG1lbnQiLCAidmFyaWFibGUiKSkgJT4lIAogIGZpbHRlcihTZWFzb24gIT0gMjAxNSkgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCBTYW1wbGVJRCwgU2l0ZSwgU2Vhc29uLCBBZ2UsIGNsYXNzaWZpY2F0aW9uKSAlPiUgCiAgc3VtbWFyaXNlKHRvdGFsID0gc3VtKFJBKSkKCmltcF9hYnVuZGFuY2VfcGxvdCA8LSBpbXBfYWJ1bmRfY29tYm8gJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCBBZ2UsIFNpdGUsIGNsYXNzaWZpY2F0aW9uKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKHRvdGFsIC8gMTApLCBzdGUgPSBzZCh0b3RhbCAvIDEwKSAvIHNxcnQobigpKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgbXV0YXRlKENvbXBhcnRtZW50ID0gZmN0X3JlbGV2ZWwoQ29tcGFydG1lbnQsICJSaGl6b3NwaGVyZSIsICJFbmRvc3BoZXJlIikpICU+JSAKICBnZ3Bsb3QoYWVzKEFnZSwgbWVhbiwgZmlsbCA9IGNsYXNzaWZpY2F0aW9uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbiAtIHN0ZSwgeW1heCA9IG1lYW4gKyBzdGUpLCAKICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSA2LjUpLAogICAgICAgICAgICAgICAgc2l6ZSA9IDAuMywKICAgICAgICAgICAgICAgIHdpZHRoID0gMC4yKSArCiAgZmFjZXRfZ3JpZChDb21wYXJ0bWVudH5TaXRlLCBzY2FsZXMgPSAiZnJlZV95IikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiZG9kZ2VyYmx1ZSIsICJnb2xkIiwgImdyZXk1MCIpKSArCiAgbGFicyh5ID0gIk1lYW4gUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCmdyaWQuYXJyYW5nZShwcmVkX3Bsb3QsIGltcF9hYnVuZGFuY2VfcGxvdCkKYGBgCgpgYGB7cn0Kb3R1X2RpcmVjdGlvbnNfY29tYm8gJT4lIAogIGlubmVyX2pvaW4odGF4LCBieSA9ICJ2YXJpYWJsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKFBoeWx1bTIsIGZpbGwgPSBwYXN0ZShPcmRlciwgUGh5bHVtMikpKSArCiAgZ2VvbV9iYXIoKSArCiAgZmFjZXRfZ3JpZChDb21wYXJ0bWVudCB+IGNsYXNzaWZpY2F0aW9uLCBzY2FsZXMgPSAiZnJlZV95IikgKwogIHRoZW1lX2J3KCkgKwogIGxhYnMoeSA9ICJOdW1iZXIgb2YgT1RVcyIsIHggPSAiIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICBjb29yZF9mbGlwKCkKCm90dV9kaXJlY3Rpb25zX2NvbWJvICU+JSAKICBpbm5lcl9qb2luKHRheCwgYnkgPSAidmFyaWFibGUiKSAlPiUgCiAgZ2dwbG90KGFlcyhQaHlsdW0yLCBjb2xvciA9IHBhc3RlKE9yZGVyLCBQaHlsdW0yKSkpICsKICBnZW9tX2JhcigpICsKICBmYWNldF9ncmlkKENvbXBhcnRtZW50IH4gY2xhc3NpZmljYXRpb24sIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgdGhlbWVfYncoKSArCiAgbGFicyh5ID0gIk51bWJlciBvZiBPVFVzIiwgeCA9ICIiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCmBgYHtyfQpvdHVfZGlyZWN0aW9uc19jb21ibyAlPiUgCiAgc2VsZWN0KENvbXBhcnRtZW50LCBjbGFzc2lmaWNhdGlvbiwgdmFyaWFibGUpICU+JSAKICBncm91cF9ieSh2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZShuID0gbigpKSAlPiUgCiAgZmlsdGVyKG4gPT0gMikKCm90dV9kaXJlY3Rpb25zX2NvbWJvICU+JSAKICBzZWxlY3QoQ29tcGFydG1lbnQsIGNsYXNzaWZpY2F0aW9uLCB2YXJpYWJsZSkgJT4lIAogIGdyb3VwX2J5KHZhcmlhYmxlLCBjbGFzc2lmaWNhdGlvbikgJT4lIAogIHN1bW1hcmlzZShuID0gbigpKSAlPiUgCiAgZmlsdGVyKG4gPT0gMikKYGBgCgoKYGBge3J9CmhlYXRfbWFwX29yZGVyIDwtIGZ1bmN0aW9uKHgpIHsKCiAgeDIgPC0geCAlPiUKICAgIHVuZ3JvdXAoKSAlPiUgCiAgICBzZWxlY3QoQWdlLCB2YXJpYWJsZSwgbWVhbl9hYnVuZCkgJT4lIAogICAgc3ByZWFkKHZhcmlhYmxlLCBtZWFuX2FidW5kKQogIAogIGhjIDwtIGhjbHVzdCh2ZWdkaXN0KHQoeDJbLC0xXSksIG1ldGhvZCA9ICJqYWNjYXJkIikpCiAgCiAgb3JkZXIgPC0gdGliYmxlKHBvc2l0aW9uID0gaGMkb3JkZXIsIG9yZGVyID0gMTpsZW5ndGgoaGMkb3JkZXIpKSAlPiUgCiAgICBhcnJhbmdlKHBvc2l0aW9uKSAlPiUgCiAgICBtdXRhdGUodmFyaWFibGUgPSBuYW1lcyh4MilbLTFdKQogIAogIHggJT4lIAogICAgaW5uZXJfam9pbihvcmRlciwgYnkgPSAidmFyaWFibGUiKQp9CgpzY2FsZWRfb3R1c19jb21ibyA8LSBiaW5kX3Jvd3ModHJhaW5fZGF0YSwgdGVzdF9kYXRhKSAlPiUKICBpbm5lcl9qb2luKHRvcF9vdHVzX2NvbWJvICU+JSB1bmdyb3VwKCkgJT4lIHNlbGVjdChDb21wYXJ0bWVudCwgdmFyaWFibGUpLCBieSA9IGMoIkNvbXBhcnRtZW50IiwgInZhcmlhYmxlIikpICU+JSAKICBmaWx0ZXIoU2Vhc29uICE9IDIwMTUpICU+JSAKICBncm91cF9ieSh2YXJpYWJsZSwgU2l0ZSwgQ29tcGFydG1lbnQpICU+JSAKICBtdXRhdGUobWluX3ZhbHVlID0gbWluKFJBKSwgbWF4X3ZhbHVlID0gbWF4KFJBKSwgc2NhbGVkX3ZhbHVlID0gKFJBIC0gbWluX3ZhbHVlKSAvIChtYXhfdmFsdWUgLSBtaW5fdmFsdWUpKSAlPiUgCiAgZ3JvdXBfYnkoU2l0ZSwgQWdlLCBDb21wYXJ0bWVudCwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UobWVhbl9hYnVuZCA9IG1lYW4oc2NhbGVkX3ZhbHVlKSkKCnBsb3R0aW5nX29yZGVyX2NvbWJvIDwtIHNjYWxlZF9vdHVzX2NvbWJvICU+JSAKICBmaWx0ZXIoU2l0ZSA9PSAiQXJidWNrbGUiKSAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIFNpdGUpICU+JSAKICBuZXN0KCkgJT4lIAogIG11dGF0ZShvcmRlciA9IG1hcChkYXRhLCB+aGVhdF9tYXBfb3JkZXIoLikpKSAlPiUgCiAgdW5uZXN0KG9yZGVyKQoKYXJiX2VzX3Bsb3QgPC0gc2NhbGVkX290dXNfY29tYm8gJT4lIAogIGlubmVyX2pvaW4ocGxvdHRpbmdfb3JkZXJfY29tYm8gJT4lIHVuZ3JvdXAoKSAlPiUgIHNlbGVjdChDb21wYXJ0bWVudCwgdmFyaWFibGUsIG9yZGVyKSwgYnkgPSBjKCJ2YXJpYWJsZSIsICJDb21wYXJ0bWVudCIpKSAlPiUgCiAgZmlsdGVyKFNpdGUgPT0gIkFyYnVja2xlIiAmIENvbXBhcnRtZW50ID09ICJFbmRvc3BoZXJlIikgJT4lIAogIGlubmVyX2pvaW4ob3R1X2RpcmVjdGlvbnNfY29tYm8sIGJ5ID0gYygidmFyaWFibGUiLCAiQ29tcGFydG1lbnQiKSkgJT4lIAogIGdncGxvdChhZXMoQWdlLCBvcmRlciwgZmlsbCA9IG1lYW5fYWJ1bmQpKSArCiAgZ2VvbV90aWxlKCkgKwogIGdlb21fcG9pbnQoYWVzKHggPSBtYXgoQWdlKSArIDcsIHkgPSBvcmRlciwgY29sb3IgPSBjbGFzc2lmaWNhdGlvbiksIHNpemUgPSAwLjUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZG9kZ2VyYmx1ZSIsICJnb2xkIiwgImdyZXkiKSkgKwogIGZhY2V0X2dyaWQoLn5TaXRlICsgQ29tcGFydG1lbnQpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvcnMgPSBicmV3ZXIucGFsKDgsICJHbkJ1IikpICsKICBsYWJzKHkgPSAiIikKCmFyYl9yc19wbG90IDwtIHNjYWxlZF9vdHVzX2NvbWJvICU+JSAKICBpbm5lcl9qb2luKHBsb3R0aW5nX29yZGVyX2NvbWJvICU+JSB1bmdyb3VwKCkgJT4lICBzZWxlY3QoQ29tcGFydG1lbnQsIHZhcmlhYmxlLCBvcmRlciksIGJ5ID0gYygidmFyaWFibGUiLCAiQ29tcGFydG1lbnQiKSkgJT4lIAogIGZpbHRlcihTaXRlID09ICJBcmJ1Y2tsZSIgJiBDb21wYXJ0bWVudCA9PSAiUmhpem9zcGhlcmUiKSAlPiUgCiAgaW5uZXJfam9pbihvdHVfZGlyZWN0aW9uc19jb21ibywgYnkgPSBjKCJ2YXJpYWJsZSIsICJDb21wYXJ0bWVudCIpKSAlPiUgCiAgZ2dwbG90KGFlcyhBZ2UsIG9yZGVyLCBmaWxsID0gbWVhbl9hYnVuZCkpICsKICBnZW9tX3RpbGUoKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IG1heChBZ2UpICsgNywgeSA9IG9yZGVyLCBjb2xvciA9IGNsYXNzaWZpY2F0aW9uKSwgc2l6ZSA9IDAuNSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJkb2RnZXJibHVlIiwgImdvbGQiLCAiZ3JleSIpKSArCiAgZmFjZXRfZ3JpZCguflNpdGUgKyBDb21wYXJ0bWVudCkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG9ycyA9IGJyZXdlci5wYWwoOCwgIkduQnUiKSkgKwogIGxhYnMoeSA9ICIiKQoKCmFya19lc19wbG90IDwtIHNjYWxlZF9vdHVzX2NvbWJvICU+JSAKICBpbm5lcl9qb2luKHBsb3R0aW5nX29yZGVyX2NvbWJvICU+JSB1bmdyb3VwKCkgJT4lICBzZWxlY3QoQ29tcGFydG1lbnQsIHZhcmlhYmxlLCBvcmRlciksIGJ5ID0gYygidmFyaWFibGUiLCAiQ29tcGFydG1lbnQiKSkgJT4lIAogIGZpbHRlcihTaXRlID09ICJKb25lc2Jvcm8iICYgQ29tcGFydG1lbnQgPT0gIkVuZG9zcGhlcmUiKSAlPiUgCiAgaW5uZXJfam9pbihvdHVfZGlyZWN0aW9uc19jb21ibywgYnkgPSBjKCJ2YXJpYWJsZSIsICJDb21wYXJ0bWVudCIpKSAlPiUgCiAgZ2dwbG90KGFlcyhBZ2UsIG9yZGVyLCBmaWxsID0gbWVhbl9hYnVuZCkpICsKICBnZW9tX3RpbGUoKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IG1heChBZ2UpICsgNywgeSA9IG9yZGVyLCBjb2xvciA9IGNsYXNzaWZpY2F0aW9uKSwgc2l6ZSA9IDAuNSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJkb2RnZXJibHVlIiwgImdvbGQiLCAiZ3JleSIpKSArCiAgZmFjZXRfZ3JpZCguflNpdGUgKyBDb21wYXJ0bWVudCkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG9ycyA9IGJyZXdlci5wYWwoOCwgIkduQnUiKSkgKwogIGxhYnMoeSA9ICIiKQoKYXJrX3JzX3Bsb3QgPC0gc2NhbGVkX290dXNfY29tYm8gJT4lIAogIGlubmVyX2pvaW4ocGxvdHRpbmdfb3JkZXJfY29tYm8gJT4lIHVuZ3JvdXAoKSAlPiUgIHNlbGVjdChDb21wYXJ0bWVudCwgdmFyaWFibGUsIG9yZGVyKSwgYnkgPSBjKCJ2YXJpYWJsZSIsICJDb21wYXJ0bWVudCIpKSAlPiUgCiAgZmlsdGVyKFNpdGUgPT0gIkpvbmVzYm9ybyIgJiBDb21wYXJ0bWVudCA9PSAiUmhpem9zcGhlcmUiKSAlPiUgCiAgaW5uZXJfam9pbihvdHVfZGlyZWN0aW9uc19jb21ibywgYnkgPSBjKCJ2YXJpYWJsZSIsICJDb21wYXJ0bWVudCIpKSAlPiUgCiAgZ2dwbG90KGFlcyhBZ2UsIG9yZGVyLCBmaWxsID0gbWVhbl9hYnVuZCkpICsKICBnZW9tX3RpbGUoKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IG1heChBZ2UpICsgNywgeSA9IG9yZGVyLCBjb2xvciA9IGNsYXNzaWZpY2F0aW9uKSwgc2l6ZSA9IDAuNSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJkb2RnZXJibHVlIiwgImdvbGQiLCAiZ3JleSIpKSArCiAgZmFjZXRfZ3JpZCguflNpdGUgKyBDb21wYXJ0bWVudCkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGNvbG9ycyA9IGJyZXdlci5wYWwoOCwgIkduQnUiKSkgKwogIGxhYnMoeSA9ICIiKQoKZ3JpZC5hcnJhbmdlKGFyYl9lc19wbG90LCBhcmtfZXNfcGxvdCwgYXJiX3JzX3Bsb3QsIGFya19yc19wbG90LCBucm93ID0gMSkKYGBgCgoKYGBge3J9CnNhZmVfbG0gPC0gcG9zc2libHkobG0sIE5BX3JlYWxfKQpzaXRlX2xtIDwtIGJpbmRfcm93cyh0cmFpbl9kYXRhLCB0ZXN0X2RhdGEpICU+JQogIGZpbHRlcihDb21wYXJ0bWVudCA9PSAiRW5kb3NwaGVyZSIgfCBDb21wYXJ0bWVudCA9PSAiUmhpem9zcGhlcmUiKQogIGlubmVyX2pvaW4oc2FtZV9hZ2VzLCBieSA9ICJBZ2UiKSAlPiUgCiAgdW5ncm91cCgpICU+JSBzZWxlY3QoQWdlLCBTYW1wbGVJRCwgQ29tcGFydG1lbnQsIFNpdGUsIGxvZzJ2YWx1ZSwgU2Vhc29uLCB2YXJpYWJsZSkgJT4lIAogIGZpbHRlcihTaXRlID09ICJBcmJ1Y2tsZSIgfCBTaXRlID09ICJKb25lc2Jvcm8iKSAlPiUgCiAgZmlsdGVyKFNlYXNvbiAhPSAyMDE1KSAlPiUgCiAgZ3JvdXBfYnkodmFyaWFibGUsIENvbXBhcnRtZW50KSAlPiUgCiAgZmlsdGVyKHN1bShsb2cydmFsdWUgPiAwKSAvIG4oKSA+IDAuMSkgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCB2YXJpYWJsZSwgQWdlKSAlPiUgCiAgbmVzdCgpICU+JSAKICBtdXRhdGUobW9kZWwgPSBtYXAoZGF0YSwgfnRpZHkoc2FmZV9sbShsb2cydmFsdWUgfiBTaXRlLCAuKSkpKSAlPiUgCiAgdW5uZXN0KG1vZGVsKQogIApzYXZlUkRTKHNpdGVfbG0sICJ+L0dvb2dsZSBEcml2ZS9STUIvQW5hbHlzZXMvTGlmZUN5Y2xlL0RhdGEvc2l0ZV9sbS5yZHMiKQoKbG1fY2xhc3NpZmljYXRpb24gPC0gc2l0ZV9sbSAlPiUgCiAgZmlsdGVyKHAudmFsdWUgIT0gIk5hTiIgJiB0ZXJtID09ICJTaXRlSm9uZXNib3JvIikgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50KSAlPiUgCiAgZmlsdGVyKENvbXBhcnRtZW50ICE9ICJCdWxrIFNvaWwiKSAlPiUgCiAgbXV0YXRlKHAuYWRqID0gcC5hZGp1c3QocC52YWx1ZSwgImJvbiIpKSAlPiUgCiAgZmlsdGVyKHAuYWRqIDw9IDAuMDUpICU+JSAKICBtdXRhdGUoU2l0ZSA9IGlmZWxzZShlc3RpbWF0ZSA8IDAsICJBcmJ1Y2tsZSIsICJKb25lc2Jvcm8iKSkgCgpsbV9jbGFzc2lmaWNhdGlvbiAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIFNpdGUsIEFnZSkgJT4lIAogIHN1bW1hcmlzZShuID0gbigpKSAgJT4lIHVuZ3JvdXAoKSAlPiUgCiAgbXV0YXRlKENvbXBhcnRtZW50ID0gZmN0X3JlbGV2ZWwoQ29tcGFydG1lbnQsICJSaGl6b3NwaGVyZSIsICJFbmRvc3BoZXJlIikpICU+JSAKICBnZ3Bsb3QoYWVzKEFnZSwgbiwgZmlsbCA9IFNpdGUpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKwogIGZhY2V0X2dyaWQoLn5Db21wYXJ0bWVudCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNmNTc2NzBmZiIsICJzdGVlbGJsdWUiKSkgKwogIHRoZW1lX21pbmltYWwoKQoKbG1fY2xhc3NpZmljYXRpb24gJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZShuID0gbigpKSAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQpICU+JSAKICBzdW1tYXJpc2UobiA9IG4oKSkKCmxtX2NsYXNzaWZpY2F0aW9uX2FidW5kIDwtIGJpbmRfcm93cyh0cmFpbl9kYXRhLCB0ZXN0X2RhdGEpICU+JQogIGlubmVyX2pvaW4obG1fY2xhc3NpZmljYXRpb24sIGJ5ID0gYygidmFyaWFibGUiLCAiQ29tcGFydG1lbnQiLCAiU2l0ZSIsICJBZ2UiKSkgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCBTaXRlLCBBZ2UsIFNhbXBsZUlEKSAlPiUgCiAgc3VtbWFyaXNlKHRvdGFsID0gc3VtKFJBKSkKCgpsbV9jbGFzc2lmaWNhdGlvbl9hYnVuZCAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIFNpdGUsIEFnZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2FiID0gbWVhbih0b3RhbCAvIDEwKSwgc2UgPSBzZCh0b3RhbCAvIDEwKSAvIHNxcnQobigpKSkgJT4lIHVuZ3JvdXAoKSAlPiUgCiAgbXV0YXRlKENvbXBhcnRtZW50ID0gZmN0X3JlbGV2ZWwoQ29tcGFydG1lbnQsICJSaGl6b3NwaGVyZSIsICJFbmRvc3BoZXJlIikpICU+JSAKICBnZ3Bsb3QoYWVzKEFnZSwgbWVhbl9hYiwgZmlsbCA9IFNpdGUpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuX2FiIC0gc2UsIHltYXggPSBtZWFuX2FiICsgc2UpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMTIuNSksIHdpZHRoID0gMC4xLCBzaXplID0gMC4yKSArCiAgZmFjZXRfZ3JpZCgufkNvbXBhcnRtZW50KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI2Y1NzY3MGZmIiwgInN0ZWVsYmx1ZSIpKSArCiAgdGhlbWVfbWluaW1hbCgpCiAgCiAgCiAgCmxtX2NsYXNzaWZpY2F0aW9uX2FidW5kICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCwgU2l0ZSkgJT4lIAogIG5lc3QoKSAlPiUgCiAgbXV0YXRlKG1vZGVsID0gbWFwKGRhdGEsIH50aWR5KGxtKHRvdGFsIH4gQWdlLCAuKSkpKSAlPiUgCiAgdW5uZXN0KG1vZGVsKSAlPiUgCiAgZmlsdGVyKHRlcm0gIT0gIihJbnRlcmNlcHQpIikgJT4lIAogIG11dGF0ZShwLmFkaiA9IHAuYWRqdXN0KHAudmFsdWUsICJib24iKSkKICAKCmxtX2NsYXNzaWZpY2F0aW9uICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCwgU2l0ZSwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JSAKICBncm91cF9ieShjb3VudCwgU2l0ZSwgQ29tcGFydG1lbnQpICU+JSAKICBzdW1tYXJpc2UoY291bnQyID0gbigpKSAlPiUgCiAgZ2dwbG90KGFlcyhjb3VudCwgY291bnQyKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgZmFjZXRfZ3JpZChDb21wYXJ0bWVudCB+IFNpdGUpCmBgYAoKCmBgYHtyfQpsaWJyYXJ5KGJpb2Jyb29tKQpsaWJyYXJ5KGVkZ2VSKQp0aWR5REdFTCA8LSBmdW5jdGlvbih4KXsKICB5ID0gREdFTGlzdChjb3VudHMgPSB0KHggJT4lIHNlbGVjdCgtU2l0ZSwgLVNhbXBsZUlEKSksIGdyb3VwID0geCRTaXRlKQogIHJldHVybih5KQp9CgpzaXRlX21vZGVsc19zZXR1cCA8LSBiaW5kX3Jvd3ModHJhaW5fZGF0YSwgdGVzdF9kYXRhKSAlPiUgCiAgc2VsZWN0KFNhbXBsZUlELCBBZ2UsIENvbXBhcnRtZW50LCB2YXJpYWJsZSwgdmFsdWUsIFNpdGUsIFNlYXNvbikgJT4lIAogIGZpbHRlcihTaXRlID09ICJBcmJ1Y2tsZSIgfCBTaXRlID09ICJKb25lc2Jvcm8iKSAlPiUgCiAgZmlsdGVyKFNlYXNvbiAhPSAyMDE1KSAlPiUgCiAgc2VsZWN0KC1TZWFzb24pICU+JSAKICBmaWx0ZXIoQ29tcGFydG1lbnQgIT0gIkJ1bGsgU29pbCIpICU+JSAKICBncm91cF9ieShBZ2UsIENvbXBhcnRtZW50KSAlPiUgCiAgZmlsdGVyKG5yb3codGFibGUoU2l0ZSkpID4gMSkgJT4lIAogIG5lc3QoKSAlPiUgCiAgbXV0YXRlKHNwcmVhZF9kYXRhID0gbWFwKGRhdGEsIH4oc3ByZWFkKC4sIHZhcmlhYmxlLCB2YWx1ZSwgZmlsbCA9IDApKSkpICU+JSAKICBtdXRhdGUoREdFTGlzdHMgPSBtYXAoc3ByZWFkX2RhdGEsIH50aWR5REdFTCguKSkpCgpzaXRlX21vZGVscyA8LSBzaXRlX21vZGVsc19zZXR1cCAlPiUgCiAgbXV0YXRlKERHRUxpc3RzID0gbWFwKERHRUxpc3RzLCB+Y2FsY05vcm1GYWN0b3JzKC4pKSkgJT4lIAogIG11dGF0ZShER0VMaXN0cyA9IG1hcChER0VMaXN0cywgfmVzdGltYXRlQ29tbW9uRGlzcCguKSkpICU+JQogIG11dGF0ZShER0VMaXN0cyA9IG1hcChER0VMaXN0cywgfmVzdGltYXRlVGFnd2lzZURpc3AoLikpKSAlPiUKICBtdXRhdGUocmVzdWx0cyA9IG1hcChER0VMaXN0cywgfmV4YWN0VGVzdCguKSkpCgpzaXRlX21vZGVsc19yZXN1bHRzIDwtIHNpdGVfbW9kZWxzICU+JSAKICB1bm5lc3QobWFwKHJlc3VsdHMsIH50aWR5KC4pKSkgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50KSAlPiUgCiAgbXV0YXRlKHAuYWRqID0gcC5hZGp1c3QocC52YWx1ZSwgImJvbiIpKQoKc2l0ZV9zaWdzIDwtIHNpdGVfbW9kZWxzX3Jlc3VsdHMgJT4lIAogIGZpbHRlcihwLmFkaiA8PSAwLjA1KSAlPiUgCiAgbXV0YXRlKGRpcmVjdGlvbiA9IGlmZWxzZShlc3RpbWF0ZSA8IDAsICJDYWxpZm9ybmlhIiwgIkFya2Fuc2FzIikpCgpzaXRlX3NpZ3MgJT4lIAogIGdyb3VwX2J5KGRpcmVjdGlvbiwgQ29tcGFydG1lbnQsIEFnZSkgJT4lIAogIHN1bW1hcmlzZShuID0gbigpKSAlPiUgCiAgZ2dwbG90KGFlcyhBZ2UsIG4sIGZpbGwgPSBkaXJlY3Rpb24pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKwogIGZhY2V0X2dyaWQoLn5Db21wYXJ0bWVudCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoInN0ZWVsYmx1ZSIsICIjZjU3NjcwZmYiKSkgKwogIGxhYnMoeCA9ICJQbGFudCBBZ2UgKERheXMpIiwgeSA9ICJOdW1iZXIgb2YgT1RVcyIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKCnNpdGVfc3VtcyA8LSBiaW5kX3Jvd3ModHJhaW5fZGF0YSwgdGVzdF9kYXRhKSAlPiUgCiAgZmlsdGVyKFNlYXNvbiA9PSAyMDE0IHwgU2Vhc29uID09IDIwMTYpICU+JSAKICBpbm5lcl9qb2luKHNpdGVfc2lncyAlPiUgcmVuYW1lKHZhcmlhYmxlID0gZ2VuZSksIGJ5ID0gYygidmFyaWFibGUiLCAiQ29tcGFydG1lbnQiLCAiQWdlIikpICU+JSAKICBmaWx0ZXIoZGlyZWN0aW9uID09IFN0YXRlKSAlPiUgCiAgZ3JvdXBfYnkoU2FtcGxlSUQsIFN0YXRlLCBDb21wYXJ0bWVudCwgQWdlKSAlPiUgCiAgc3VtbWFyaXNlKHRvdGFsID0gc3VtKFJBKSkKCnNpdGVfc3VtcyAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIFN0YXRlKSAlPiUgCiAgbmVzdCgpICU+JSAKICBtdXRhdGUobW9kZWxzID0gbWFwKGRhdGEsIH50aWR5KGxtKHRvdGFsIH4gQWdlLC4pKSkpICU+JSAKICB1bm5lc3QobW9kZWxzKSAlPiUgCiAgZmlsdGVyKHRlcm0gPT0gIkFnZSIpICU+JSAKICBtdXRhdGUocC5hZGogPSBwLmFkanVzdChwLnZhbHVlLCAiYm9uIikpCgp0b3RhbF9wbG90IDwtIHNpdGVfc3VtcyAlPiUgCiAgZ3JvdXBfYnkoU3RhdGUsIENvbXBhcnRtZW50LCBBZ2UpICU+JSAKICBzdW1tYXJpc2UobWVhbl90b3RhbCA9IG1lYW4odG90YWwvMTApLCBzZSA9IHNkKHRvdGFsLzEwKS9zcXJ0KG4oKSkpICU+JSB1bmdyb3VwKCkgJT4lIAogIG11dGF0ZShDb21wYXJ0bWVudCA9IGZjdF9yZWxldmVsKENvbXBhcnRtZW50LCAiUmhpem9zcGhlcmUiLCAiRW5kb3NwaGVyZSIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gQWdlLCB5ID0gbWVhbl90b3RhbCwgZmlsbCA9IFN0YXRlKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbl90b3RhbCAtIHNlLCB5bWF4ID0gbWVhbl90b3RhbCArIHNlKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgxMi41KSwgc2l6ZSA9IDAuNSwgd2lkdGggPSAwLjIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJzdGVlbGJsdWUiLCAiI2Y1NzY3MGZmIikpICsKICBmYWNldF9ncmlkKC5+Q29tcGFydG1lbnQpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoeCA9ICIiLCB5ID0gIiIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCmBgYAoKCkFyZSBlYXJseSBjb2xvbml6aW5nIE9UVXMgZGlmZmVyZW50aWFsbHkgYWJ1bmRhbnQgZnJvbSB0aGUgc29pbApgYGB7cn0KY29tcF9sbV9tb2RlbCA8LSBiaW5kX3Jvd3ModHJhaW5fZGF0YSwgdGVzdF9kYXRhKSAlPiUgc2VsZWN0KEFnZSwgQ29tcGFydG1lbnQsIHZhcmlhYmxlLCBsb2cydmFsdWUsIFNpdGUsIFNlYXNvbikgJT4lIAogIGZpbHRlcihTaXRlID09ICJBcmJ1Y2tsZSIgfCBTaXRlID09ICJKb25lc2Jvcm8iKSAlPiUgCiAgaW5uZXJfam9pbihvdHVfZGlyZWN0aW9uc19jb21ibyAlPiUgdW5ncm91cCgpICU+JSByZW5hbWUob3R1X2NvbXBhcnRtZW50ID0gQ29tcGFydG1lbnQpLCBieSA9IGMoInZhcmlhYmxlIikpICU+JQogIGdyb3VwX2J5KHZhcmlhYmxlLCBjbGFzc2lmaWNhdGlvbiwgb3R1X2NvbXBhcnRtZW50KSAlPiUgCiAgZmlsdGVyKEFnZSA8IDQ5KSAlPiUgCiAgbmVzdCgpICU+JSAKICBtdXRhdGUobW9kZWwgPSBtYXAoZGF0YSwgfnRpZHkobG0obG9nMnZhbHVlIH4gQ29tcGFydG1lbnQsIC4pKSkpICU+JSAKICB1bm5lc3QobW9kZWwpCiAgCmNvbXBfbG1fbW9kZWxfcmVzdWx0cyA8LSBjb21wX2xtX21vZGVsICU+JSAKICBmaWx0ZXIodGVybSAhPSAiKEludGVyY2VwdCkiKSAlPiUgCiAgZ3JvdXBfYnkob3R1X2NvbXBhcnRtZW50KSAlPiUgCiAgbXV0YXRlKHAuYWRqID0gcC5hZGp1c3QocC52YWx1ZSwgImJvbiIpKSAlPiUgCiAgbXV0YXRlKHRlcm0gPSAgZ3N1YigiQ29tcGFydG1lbnQiLCAiIiwgdGVybSkpICU+JSAKICBmaWx0ZXIob3R1X2NvbXBhcnRtZW50ID09IHRlcm0pICU+JSAKICByZW5hbWUoQ29tcGFydG1lbnQgPSBvdHVfY29tcGFydG1lbnQpICU+JSAKICBtdXRhdGUoRW5yaWNobWVudCA9IGlmZWxzZShlc3RpbWF0ZSA+IDAsICJFbnJpY2hlZCIsICJEZXBsZXRlZCIpKSAlPiUgCiAgbXV0YXRlKGNvbXBfY2xhc3NpZmljYXRpb24gPSBpZmVsc2UocC5hZGogPiAwLjA1LCAiTmV1dHJhbCIsIEVucmljaG1lbnQpKSAlPiUgCiAgcmVuYW1lKGNvbXBfZXN0aW1hdGUgPSBlc3RpbWF0ZSwgY29tcF9wLmFkaiA9IHAuYWRqKQoKb3R1X2RpcmVjdGlvbnNfY29tYm8gJT4lIAogIHJlbmFtZShkaXJlY3Rpb25fZXN0aW1hdGUgPSBlc3RpbWF0ZSwgZGlyZWN0aW9uX3AuYWRqID0gcC5hZGopICU+JSAKICBpbm5lcl9qb2luKGNvbXBfbG1fbW9kZWxfcmVzdWx0cywgYnkgPSBjKCJDb21wYXJ0bWVudCIsICJ2YXJpYWJsZSIsICJjbGFzc2lmaWNhdGlvbiIpKSAlPiUgCiAgI2ZpbHRlcihjbGFzc2lmaWNhdGlvbiAhPSAiTmV1dHJhbCIpICU+JSAKICBtdXRhdGUoc2lnID0gaWZlbHNlKGNvbXBfcC5hZGogPD0gMC4wNSwgInNpZyIsICJucyIpKSAlPiUgCiAgZ3JvdXBfYnkoY2xhc3NpZmljYXRpb24pICU+JSAKICBtdXRhdGUoQ29tcGFydG1lbnQgPSBmY3RfcmVsZXZlbChDb21wYXJ0bWVudCwgIlJoaXpvc3BoZXJlIiwgIkVuZG9zcGhlcmUiKSkgJT4lIAogIGdncGxvdChhZXMoZGlyZWN0aW9uX2VzdGltYXRlLCBjb21wX2VzdGltYXRlLCBjb2xvciA9IGNsYXNzaWZpY2F0aW9uLCBzaGFwZSA9IHNpZykpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMSwgMTYpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImRvZGdlcmJsdWUiLCAiZ29sZCIsICJncmV5NTAiKSkgKwogIGZhY2V0X2dyaWQoLn5Db21wYXJ0bWVudCwgc2NhbGVzID0gImZyZWVfeCIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoeCA9ICJBZ2Ugc2xvcGUgZXN0aW1hdGUiLCB5ID0gIkxvZzIgZm9sZCBjaGFuZ2UgZnJvbSBidWxrIHNvaWwiKSArIAogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKICAKCmBgYAoKCmBgYHtyfQpsaWJyYXJ5KGJyb29tKQpsaWJyYXJ5KHNwbGluZXMpCm1vZGVsX2RhdGEgPC0gYmluZF9yb3dzKHRlc3RfZGF0YSwgdHJhaW5fZGF0YSkgJT4lIAogIGZpbHRlcihTaXRlID09ICJBcmJ1Y2tsZSIgJiBTZWFzb24gPT0gMjAxNCkgJT4lIAogIGlubmVyX2pvaW4ob3R1X2RpcmVjdGlvbnNfY29tYm8gJT4lIHVuZ3JvdXAoKSAlPiUgc2VsZWN0KENvbXBhcnRtZW50LCB2YXJpYWJsZSwgY2xhc3NpZmljYXRpb24pLCBieSA9IGMoInZhcmlhYmxlIiwgIkNvbXBhcnRtZW50IikpCgptb2QgPC0gfmdsbShjYmluZChvdHVfdG90YWwsIGRlcHRoX3RvdGFsIC0gb3R1X3RvdGFsKSB+IG5zKEFnZSwgNCksIC4sIGZhbWlseSA9ICJiaW5vbWlhbCIpCgpzcGxpbmVfcHJlZGljdGlvbnNfcnMgPC0gbW9kZWxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoQWdlLCBDb21wYXJ0bWVudCwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UoZGVwdGhfdG90YWwgPSBzdW0oRGVwdGgpLCBvdHVfdG90YWwgPSBzdW0odmFsdWUpKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBvdHVfdG90YWwvZGVwdGhfdG90YWwpICU+JQogIGZpbHRlcihDb21wYXJ0bWVudCA9PSAiUmhpem9zcGhlcmUiKSAlPiUgCiAgZ3JvdXBfYnkodmFyaWFibGUpICU+JSAKICBuZXN0KCkgJT4lIAogIG11dGF0ZShtb2RlbCA9IG1hcChkYXRhLCBtb2QpKSAlPiUKICB1bm5lc3QobWFwMihtb2RlbCwgZGF0YSwgYXVnbWVudCwgdHlwZS5wcmVkaWN0ID0gInJlc3BvbnNlIikpCgpwZWFrX3Blcl9hZ2VfcnMgPC0gc3BsaW5lX3ByZWRpY3Rpb25zX3JzICU+JQogIGdyb3VwX2J5KHZhcmlhYmxlKSAlPiUKICBtdXRhdGUoYXZlcmFnZSA9IG1lYW4oLmZpdHRlZCkpICU+JSAKICB0b3BfbigxLCAuZml0dGVkKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKHJhdGlvID0gLmZpdHRlZCAvIGF2ZXJhZ2UpCiAgdG9wX24oMTYsIHJhdGlvKQogIGZpbHRlcihBZ2UgIT0gbWluKEFnZSksIEFnZSAhPSBtYXgoQWdlKSkKICAKc3BsaW5lX3ByZWRpY3Rpb25zX2VzIDwtIG1vZGVsX2RhdGEgJT4lIAogIGdyb3VwX2J5KEFnZSwgQ29tcGFydG1lbnQsIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKGRlcHRoX3RvdGFsID0gc3VtKERlcHRoKSwgb3R1X3RvdGFsID0gc3VtKHZhbHVlKSkgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gb3R1X3RvdGFsL2RlcHRoX3RvdGFsKSAlPiUKICBmaWx0ZXIoQ29tcGFydG1lbnQgPT0gIkVuZG9zcGhlcmUiKSAlPiUgCiAgZ3JvdXBfYnkodmFyaWFibGUpICU+JSAKICBuZXN0KCkgJT4lIAogIG11dGF0ZShtb2RlbCA9IG1hcChkYXRhLCBtb2QpKSAlPiUKICB1bm5lc3QobWFwMihtb2RlbCwgZGF0YSwgYXVnbWVudCwgdHlwZS5wcmVkaWN0ID0gInJlc3BvbnNlIikpCgpwZWFrX3Blcl9hZ2VfZXMgPC0gc3BsaW5lX3ByZWRpY3Rpb25zX2VzICU+JQogIGdyb3VwX2J5KHZhcmlhYmxlKSAlPiUKICBtdXRhdGUoYXZlcmFnZSA9IG1lYW4oLmZpdHRlZCkpICU+JSAKICB0b3BfbigxLCAuZml0dGVkKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKHJhdGlvID0gLmZpdHRlZCAvIGF2ZXJhZ2UpCiAgdG9wX24oMTYsIHJhdGlvKQogIGZpbHRlcihBZ2UgIT0gbWluKEFnZSksIEFnZSAhPSBtYXgoQWdlKSkKCmVzX3Bsb3QgPC0gcGVha19wZXJfYWdlX2VzICU+JQogIHNlbGVjdCh2YXJpYWJsZSwgcGVhayA9IEFnZSkgJT4lCiAgaW5uZXJfam9pbihzcGxpbmVfcHJlZGljdGlvbnNfZXMsIGJ5ID0gInZhcmlhYmxlIikgJT4lCiAgaW5uZXJfam9pbih0YXgsIGJ5ID0gInZhcmlhYmxlIikgJT4lIAogIG11dGF0ZShncm91cF92YXIgPSBwYXN0ZSh2YXJpYWJsZSwgRmFtaWx5KSkgJT4lIAogIGdyb3VwX2J5KHZhcmlhYmxlKSAlPiUgCiAgbXV0YXRlKHNjYWxlZF9wZXJjZW50ID0gKHBlcmNlbnQgLSBtaW4ocGVyY2VudCkpIC8gKG1heChwZXJjZW50KSAtIG1pbihwZXJjZW50KSksCiAgICAgICAgIHNjYWxlZF9maXQgPSAoLmZpdHRlZCAtIG1pbiguZml0dGVkKSkgLyAobWF4KC5maXR0ZWQpIC0gbWluKC5maXR0ZWQpKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgbXV0YXRlKHZhcmlhYmxlID0gcmVvcmRlcih2YXJpYWJsZSwgcGVhaykpICU+JSAKICBhcnJhbmdlKHZhcmlhYmxlKSAlPiUgCiAgbXV0YXRlKHZhcmlhYmxlLmYgPSByZW9yZGVyKGFzLmNoYXJhY3Rlcih2YXJpYWJsZSksIGRlc2ModmFyaWFibGUpKSkgJT4lIAogIGdyb3VwX2J5KHZhcmlhYmxlLmYpICU+JQogIG5lc3QoLXZhcmlhYmxlLmYpICU+JSAKICBtdXRhdGUob3JkZXIgPSAoMDoobnJvdyguKS0xKSkqMC41KSAlPiUgCiAgbXV0YXRlKG9yZGVyMiA9IDE6bnJvdyguKSkgJT4lIAogIHVubmVzdCgpICU+JSAKICBpbm5lcl9qb2luKG90dV9kaXJlY3Rpb25zX2NvbWJvICU+JSB1bmdyb3VwKCkgJT4lIHNlbGVjdChDb21wYXJ0bWVudCwgY2xhc3NpZmljYXRpb24sIHZhcmlhYmxlKSwgYnkgPSBjKCJ2YXJpYWJsZSIsICJDb21wYXJ0bWVudCIpKSAlPiUgCiAgZ2dwbG90KGFlcyhBZ2UsIHNjYWxlZF9wZXJjZW50LCBncm91cCA9IHZhcmlhYmxlLmYpKSArCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBvcmRlciwgeW1heCA9IG9yZGVyK3NjYWxlZF9wZXJjZW50LCBmaWxsID0gY2xhc3NpZmljYXRpb24pLCBjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSAwLjQpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoKSArCiAgZXhwYW5kX2xpbWl0cyh5ID0gMCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoImRvZGdlcmJsdWUiLCAiZ29sZCIsICJncmV5NTAiKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh5ID0gIiIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsLTAuNSksIHVuaXRzID0gImNtIikpCgpyc19wbG90IDwtIHBlYWtfcGVyX2FnZV9ycyAlPiUKICBzZWxlY3QodmFyaWFibGUsIHBlYWsgPSBBZ2UpICU+JQogIGlubmVyX2pvaW4oc3BsaW5lX3ByZWRpY3Rpb25zX3JzLCBieSA9ICJ2YXJpYWJsZSIpICU+JQogIGlubmVyX2pvaW4odGF4LCBieSA9ICJ2YXJpYWJsZSIpICU+JSAKICBtdXRhdGUoZ3JvdXBfdmFyID0gcGFzdGUodmFyaWFibGUsIEZhbWlseSkpICU+JSAKICBncm91cF9ieSh2YXJpYWJsZSkgJT4lIAogIG11dGF0ZShzY2FsZWRfcGVyY2VudCA9IChwZXJjZW50IC0gbWluKHBlcmNlbnQpKSAvIChtYXgocGVyY2VudCkgLSBtaW4ocGVyY2VudCkpLAogICAgICAgICBzY2FsZWRfZml0ID0gKC5maXR0ZWQgLSBtaW4oLmZpdHRlZCkpIC8gKG1heCguZml0dGVkKSAtIG1pbiguZml0dGVkKSkpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIG11dGF0ZSh2YXJpYWJsZSA9IHJlb3JkZXIodmFyaWFibGUsIHBlYWspKSAlPiUgCiAgYXJyYW5nZSh2YXJpYWJsZSkgJT4lIAogIG11dGF0ZSh2YXJpYWJsZS5mID0gcmVvcmRlcihhcy5jaGFyYWN0ZXIodmFyaWFibGUpLCBkZXNjKHZhcmlhYmxlKSkpICU+JSAKICBncm91cF9ieSh2YXJpYWJsZS5mKSAlPiUKICBuZXN0KC12YXJpYWJsZS5mKSAlPiUgCiAgbXV0YXRlKG9yZGVyID0gKDA6KG5yb3coLiktMSkpKjAuNSkgJT4lIAogIG11dGF0ZShvcmRlcjIgPSAxOm5yb3coLikpICU+JSAKICB1bm5lc3QoKSAlPiUgCiAgaW5uZXJfam9pbihvdHVfZGlyZWN0aW9uc19jb21ibyAlPiUgdW5ncm91cCgpICU+JSBzZWxlY3QoQ29tcGFydG1lbnQsIGNsYXNzaWZpY2F0aW9uLCB2YXJpYWJsZSksIGJ5ID0gYygidmFyaWFibGUiLCAiQ29tcGFydG1lbnQiKSkgJT4lIAogIGdncGxvdChhZXMoQWdlLCBzY2FsZWRfcGVyY2VudCwgZ3JvdXAgPSB2YXJpYWJsZS5mKSkgKwogIGdlb21fcmliYm9uKGFlcyh5bWluID0gb3JkZXIsIHltYXggPSBvcmRlcitzY2FsZWRfcGVyY2VudCwgZmlsbCA9IGNsYXNzaWZpY2F0aW9uKSwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gMC40KSArCiAgc2NhbGVfeV9jb250aW51b3VzKCkgKwogIGV4cGFuZF9saW1pdHMoeSA9IDApICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJkb2RnZXJibHVlIiwgImdvbGQiLCAiZ3JleTUwIikpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoeSA9ICIiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDEsLTAuNSwxLDEpLCB1bml0cyA9ICJjbSIpKQoKZ3JpZC5hcnJhbmdlKHJzX3Bsb3QsIGVzX3Bsb3QsIG5yb3cgPSAxKQoKYGBgCgpgYGB7cn0KcGh5X2RhdGEgPC0gYmluZF9yb3dzKHRlc3RfZGF0YSwgdHJhaW5fZGF0YSkgJT4lIAogIGZpbHRlcihTaXRlID09ICJBcmJ1Y2tsZSIgfCBTaXRlID09ICJKb25lc2Jvcm8iKSAlPiUgCiAgaW5uZXJfam9pbih0YXgsIGJ5ID0gInZhcmlhYmxlIikgJT4lIAogIGdyb3VwX2J5KFNhbXBsZUlELCBBZ2UsIENvbXBhcnRtZW50LCBsZXZlbCA9IHBhc3RlKE9yZGVyLCBGYW1pbHkpKSAlPiUgCiAgc3VtbWFyaXNlKHRvdGFsID0gc3VtKFJBKSkKCnBoeV9kYXRhICU+JSAKICAjZmlsdGVyKEZhbWlseSAhPSAidW5jbGFzc2lmaWVkIikgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCBsZXZlbCkgJT4lIAogIHN1bW1hcmlzZShtZWFuID0gbWVhbih0b3RhbCkpICU+JSAKICB0b3BfbigzLCBtZWFuKQoKcGh5X2RhdGEgJT4lIAogIGdyb3VwX2J5KENvbXBhcnRtZW50LCBGYW1pbHkpICU+JSAKICBuZXN0KCkgJT4lIAogIG11dGF0ZShtb2RlbCA9IG1hcChkYXRhLCB+dGlkeShsbShsb2cyKHRvdGFsICsgMSkgfiBBZ2UsIC4pKSkpICU+JSAKICB1bm5lc3QobW9kZWwpICU+JSAKICBmaWx0ZXIodGVybSAhPSAiKEludGVyY2VwdCkiKSAlPiUgCiAgbXV0YXRlKHAuYWRqID0gcC5hZGp1c3QocC52YWx1ZSwgImJvbiIpKQogIHN1bW1hcmlzZShtZWFuID0gbWVhbih0b3RhbCkpICU+JSAKICAjZmlsdGVyKEZhbWlseSA9PSAiTXl4b2NvY2NhY2VhZSIpICU+JSAKICBnZ3Bsb3QoYWVzKEFnZSwgbWVhbiwgZmlsbCA9IEdlbnVzKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgZmFjZXRfZ3JpZCgufkNvbXBhcnRtZW50KQpgYGAKCmBgYHtyfQpkdC50YWJsZSA8LSByZWFkLnRhYmxlKCJ+L0dvb2dsZSBEcml2ZS9STUIvQW5hbHlzZXMvTGlmZUN5Y2xlL0RhdGEvRFJPVUdIVC9kcm91Z2h0X290dV90YWJsZS50eHQiLCBoZWFkZXIgPSBULCByb3cubmFtZXMgPSAxKQpkdC5tYXAgPC0gcmVhZC50YWJsZSgifi9Hb29nbGUgRHJpdmUvUk1CL0FuYWx5c2VzL0xpZmVDeWNsZS9EYXRhL0RST1VHSFQvZHJvdWdodC5tYXAiLCBoZWFkZXIgPSBUKQpvcmcgPC0gcmVhZFJEUygifi9STUIvUmVmZXJlbmNlL29yZ2FuZWxsZS5yZHMiKQoKZHQudGFibGUgPC0gZHQudGFibGVbIXJvdy5uYW1lcyhkdC50YWJsZSklaW4lb3JnLF0KZHQudGFibGUgPC0gZHQudGFibGVbLG1hdGNoKGR0Lm1hcCRTYW1wbGVJRCxjb2xuYW1lcyhkdC50YWJsZSkpXQoKYWJzZW50X290dXMgPC0gdG9wX290dXNfY29tYm8kdmFyaWFibGVbIXRvcF9vdHVzX2NvbWJvJHZhcmlhYmxlJWluJXJvdy5uYW1lcyhkdC50YWJsZSldCgphYnNlbnRfb3R1c19kZiA8LSBkYXRhLmZyYW1lKG1hdHJpeCgwLCBucm93ID0gbGVuZ3RoKGFic2VudF9vdHVzKSwgbmNvbCA9IG5jb2woZHQudGFibGUpKSkKcm93Lm5hbWVzKGFic2VudF9vdHVzX2RmKSA8LSBhYnNlbnRfb3R1cwpjb2xuYW1lcyhhYnNlbnRfb3R1c19kZikgPC0gY29sbmFtZXMoZHQudGFibGUpCgpkdC5kYXRhIDwtIG1lbHQoY2JpbmQoZHQubWFwLCB0KHJiaW5kKGR0LnRhYmxlLCBhYnNlbnRfb3R1c19kZikpKSwgaWQudmFycyA9IG5hbWVzKGR0Lm1hcCkpICU+JSAKICBzZWxlY3QoLUJhcmNvZGVTZXF1ZW5jZSwgLUxpbmtlclByaW1lclNlcXVlbmNlKQpkdC5kYXRhIDwtIGR0LmRhdGEgJT4lIAogIGdyb3VwX2J5KFNhbXBsZUlEKSAlPiUgCiAgbXV0YXRlKGRlcHRoID0gc3VtKHZhbHVlKSkgJT4lIAogIG11dGF0ZShSQSA9ICh2YWx1ZSAvIGRlcHRoKSAqIDEwMDAsIGxvZzJ2YWx1ZSA9IGxvZzIoUkEgKyAxKSkKCgpzYWZlX3ByZWRpY3QgPC0gcG9zc2libHkocHJlZGljdCwgTkFfcmVhbF8pCgptb2RlbF90ZXN0X3ByZWRpY3Rpb25zX2Ryb3VnaHQgPC0gdG9wX290dXNfY29tYm8gJT4lIHVuZ3JvdXAoKSAlPiUgc2VsZWN0KENvbXBhcnRtZW50LCB2YXJpYWJsZSkgJT4lIAogIGxlZnRfam9pbihkdC5kYXRhLCBieSA9IGMoInZhcmlhYmxlIiwgIkNvbXBhcnRtZW50IikpICU+JSAKICBzZWxlY3QoU2FtcGxlSUQsIHZhcmlhYmxlLCBDb21wYXJ0bWVudCwgU29pbCwgQ3VsdGl2YXIsIFRyZWF0bWVudCwgbG9nMnZhbHVlKSAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIFNvaWwsIFNhbXBsZUlELCBDdWx0aXZhciwgVHJlYXRtZW50KSAlPiUgCiAgbXV0YXRlKGxvZzJ2YWx1ZSA9IGlmZWxzZShpcy5uYShsb2cydmFsdWUpLCAwLCBsb2cydmFsdWUpKSAlPiUgCiAgbmVzdCgpICU+JSAKICBtdXRhdGUoc3ByZWFkX2RhdGEgPSBtYXAoZGF0YSwgfihzcHJlYWQoLiwgdmFyaWFibGUsIGxvZzJ2YWx1ZSwgZmlsbCA9IDApKSkpICU+JSAKICBzZWxlY3QoLWRhdGEpICU+JSAKICBpbm5lcl9qb2luKHJmX3NwYXJzZV9jb21ibyAlPiUgdW5ncm91cCgpICU+JSBzZWxlY3QoQ29tcGFydG1lbnQsIHJmKSwgYnkgPSAiQ29tcGFydG1lbnQiKSAlPiUgCiAgbXV0YXRlKHByZWRpY3Rpb25zID0gbWFwMihyZiwgc3ByZWFkX2RhdGEsIHNhZmVfcHJlZGljdCkpICU+JSAKICBtdXRhdGUobW9kZWwgPSBDb21wYXJ0bWVudCkgJT4lIAogIHVubmVzdChwcmVkaWN0aW9ucykKCm1vZGVsX3Rlc3RfcHJlZGljdGlvbnNfZHJvdWdodCAlPiUgCiAgc2VsZWN0KENvbXBhcnRtZW50LCBTYW1wbGVJRCwgU29pbCwgQ3VsdGl2YXIsIFRyZWF0bWVudCwgcHJlZGljdGlvbnMpICU+JSAKICB1bmdyb3VwKCkgJT4lIHdyaXRlX3RzdiguLCAifi9Hb29nbGUgRHJpdmUvUk1CL0FuYWx5c2VzL0xpZmVDeWNsZS9UQUJMRVMvZHJvdWdodF9hZ2VfcHJlZGljdGlvbnMudHN2IikKCiAgCmRyX3ByZWRfcGxvdCA8LSBtb2RlbF90ZXN0X3ByZWRpY3Rpb25zX2Ryb3VnaHQgJT4lIAogIG11dGF0ZShDb21wYXJ0bWVudCA9IGZjdF9yZWxldmVsKENvbXBhcnRtZW50LCAiUmhpem9zcGhlcmUiLCAiRW5kb3NwaGVyZSIpKSAlPiUgCiAgZ2dwbG90KGFlcyhTb2lsLCBwcmVkaWN0aW9ucywgZmlsbCA9IFRyZWF0bWVudCkpICsKICAjZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNDksIGxpbmV0eXBlID0gImRvdHRlZCIpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5zaXplID0gMC41LCBhbHBoYSA9IDEpICsKICBmYWNldF9ncmlkKC5+Q29tcGFydG1lbnQpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNEOEIzNjUiLCAiIzVBQjRBQyIpKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiTWljcm9iaW90YSBBZ2UgKERheXMpIikgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyfQp3aG9sZV9hbm92YSA8LSBhb3YocHJlZGljdGlvbnMgfiBDb21wYXJ0bWVudCAqIFNvaWwgKiBUcmVhdG1lbnQsIG1vZGVsX3Rlc3RfcHJlZGljdGlvbnNfZHJvdWdodCkKdGlkeShUdWtleUhTRCh3aG9sZV9hbm92YSkpCnRpZHkod2hvbGVfYW5vdmEpCgoKbW9kZWxfdGVzdF9wcmVkaWN0aW9uc19kcm91Z2h0ICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCkgJT4lIAogIG5lc3QoKSAlPiUgCiAgbXV0YXRlKG1vZGVsID0gbWFwKGRhdGEsIH50aWR5KGFvdihwcmVkaWN0aW9ucyB+IFRyZWF0bWVudCwgLikpKSkgJT4lIAogIHVubmVzdChtb2RlbCkKCm1vZGVsX3Rlc3RfcHJlZGljdGlvbnNfZHJvdWdodCAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIFNvaWwpICU+JQogIG5lc3QoKSAlPiUgCiAgbXV0YXRlKG1vZGVsID0gbWFwKGRhdGEsIH50aWR5KGFvdihwcmVkaWN0aW9ucyB+IFRyZWF0bWVudCwgLikpKSkgJT4lIAogIHVubmVzdChtb2RlbCkKCm1vZGVsX3Rlc3RfcHJlZGljdGlvbnNfZHJvdWdodCAlPiUgCiAgZ3JvdXBfYnkoQ29tcGFydG1lbnQsIFNvaWwpICU+JQogIG5lc3QoKSAlPiUgCiAgbXV0YXRlKG1vZGVsID0gbWFwKGRhdGEsIH50aWR5KGxtKHByZWRpY3Rpb25zIH4gVHJlYXRtZW50LCAuKSkpKSAlPiUgCiAgdW5uZXN0KG1vZGVsKSAlPiUgCiAgZmlsdGVyKHRlcm0gIT0gIihJbnRlcmNlcHQpIikgJT4lIAogIG11dGF0ZShwLmFkaiA9IHAuYWRqdXN0KHAudmFsdWUsICJib24iKSkKYGBgCgpgYGB7cn0KbW9kZWxfdGVzdF9wcmVkaWN0aW9uc19kcm91Z2h0ICU+JSAKICB1bm5lc3QocHJlZGljdGlvbnMpICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCwgU29pbCkgJT4lCiAgbmVzdCgpICU+JSAKICBtdXRhdGUoYW4gPSBtYXAoZGF0YSwgfmFvdihwcmVkaWN0aW9ucyB+IFRyZWF0bWVudCAqIEN1bHRpdmFyLCAuKSkpICU+JSAKICBtdXRhdGUodGhzdCA9IG1hcChhbiwgfnRpZHkoVHVrZXlIU0QoLikpKSkgJT4lIAogIHVubmVzdCh0aHN0KSAlPiUgCiAgZmlsdGVyKGFkai5wLnZhbHVlIDw9IDAuMDUpCmBgYAoKYGBge3J9CmRyX2NsYXNzX3Bsb3QgPC0gZHQuZGF0YSAlPiUgCiAgaW5uZXJfam9pbihvdHVfZGlyZWN0aW9uc19jb21ibywgYnkgPSBjKCJ2YXJpYWJsZSIsICJDb21wYXJ0bWVudCIpKSAlPiUgCiAgZ3JvdXBfYnkoU2FtcGxlSUQsIGNsYXNzaWZpY2F0aW9uLCBUcmVhdG1lbnQsIENvbXBhcnRtZW50LCBTb2lsKSAlPiUgCiAgc3VtbWFyaXNlKHRvdGFsID0gc3VtKFJBKSkgJT4lIAogIGdyb3VwX2J5KGNsYXNzaWZpY2F0aW9uLCBUcmVhdG1lbnQsIENvbXBhcnRtZW50LCBTb2lsKSAlPiUgCiAgbXV0YXRlKG1lYW5fdG90YWwgPSBtZWFuKHRvdGFsLyAxMCksIHNlX3RvdGFsID0gc2QodG90YWwvMTApIC8gc3FydChuKCkpKSAlPiUgCiAgZmlsdGVyKENvbXBhcnRtZW50ID09ICJFbmRvc3BoZXJlIikgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgbXV0YXRlKGNsYXNzaWZpY2F0aW9uID0gZmN0X3JlbGV2ZWwoY2xhc3NpZmljYXRpb24sICJEZWNyZWFzaW5nIiwgIk5ldXRyYWwiLCAiSW5jcmVhc2luZyIpKSAlPiUgCiAgZ2dwbG90KGFlcyhTb2lsLCBtZWFuX3RvdGFsLCBmaWxsID0gVHJlYXRtZW50KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbl90b3RhbCAtIHNlX3RvdGFsLCB5bWF4ID0gbWVhbl90b3RhbCArIHNlX3RvdGFsKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIHNpemUgPSAwLjI1LCB3aWR0aCA9IDAuMikgKwogIGZhY2V0X3dyYXAoIH4gY2xhc3NpZmljYXRpb24sIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0Q4QjM2NSIsICIjNUFCNEFDIikpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoeCA9ICIiLCB5ID0gIk1lYW4gUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLCB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCmdyaWQuYXJyYW5nZShkcl9wcmVkX3Bsb3QsIGRyX2NsYXNzX3Bsb3QpCmBgYAoKYGBge3J9CmNsYXNzX2FidW5kX3R1a2V5IDwtIGR0LmRhdGEgJT4lIAogIGlubmVyX2pvaW4ob3R1X2RpcmVjdGlvbnNfY29tYm8sIGJ5ID0gYygidmFyaWFibGUiLCAiQ29tcGFydG1lbnQiKSkgJT4lIAogIGdyb3VwX2J5KFNhbXBsZUlELCBjbGFzc2lmaWNhdGlvbiwgVHJlYXRtZW50LCBDb21wYXJ0bWVudCwgU29pbCkgJT4lIAogIHN1bW1hcmlzZSh0b3RhbCA9IHN1bShSQS8xMCkpICU+JSAKICBncm91cF9ieShDb21wYXJ0bWVudCwgY2xhc3NpZmljYXRpb24sIFNvaWwpICU+JSAKICBuZXN0KCkgJT4lIAogIG11dGF0ZShtb2RlbCA9IG1hcChkYXRhLCB+YW92KHRvdGFsIH4gVHJlYXRtZW50LC4pKSkgJT4lIAogIG11dGF0ZSh0aHNkID0gbWFwKG1vZGVsLCB+dGlkeShUdWtleUhTRCguKSkpKSAlPiUgCiAgdW5uZXN0KHRoc2QpICU+JSAKICAjZmlsdGVyKHRlcm0gIT0gIihJbnRlcmNlcHQpIikgJT4lIAogICNtdXRhdGUocC5hZGogPSBwLmFkanVzdChwLnZhbHVlLCAiQkgiKSkgJT4lIAogIGZpbHRlcihDb21wYXJ0bWVudCA9PSAiRW5kb3NwaGVyZSIpICU+JSAKICBzZWxlY3QoLWRhdGEsIC1tb2RlbCwgLXRlcm0pCmBgYAoKCgoK